主页
主页
文章目录
  1. 1. promise then
    1. (1) 返回一个新的promise。实现链式调用
    2. (2)如果then中执行后返回的还是一个promise
    3. (3)返回值为promise
  2. 2. Promise.resolve() 和 Promise.reject()
    1. (1)参数是一个 Promise 实例
    2. (2)参数是一个thenable对象
    3. (3)参数不是具有then方法的对象,或根本就不是对象
    4. (4)不带有任何参数

promise中

1. promise then

上一节promise上已经根据promise/A+规范写出了基本的Promise类的基本框架。

那么在promise/A+规范中还有几个关于then中的规范没有实现。

  1. 如果返回一个普通值,会走下一个then的成功回调
  2. 如果返回一个promise,会将他执行完的状态给下一个then
  3. 如果抛出错误,会走下一个then的reject方法
  4. 返回一个新的promise。实现链式调用

(1) 返回一个新的promise。实现链式调用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
then(onFulfilled, onRejected) {
onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : val => val;
onRejected = typeof onRejected === 'function' ? onRejected : err => { throw err};
// 因为then中的回调函数是异步执行的。为了确保newPromise存在,需要setTimeout
let newPromise = new Promise((resolve, reject) => {
setTimeout(() => {
if (this.status === FULFILLED) {
// 如果执行then中报错,需要直接reject
try {
// 执行下then中的方法的返回值当成下一个then的参数传递
let x = onFulfilled(this.value);
// 返回值有多种情况。普通值或者还是一个promise
resolvePromise(newPromise, x, resolve, reject);
} catch(err) {
reject(err)
}
}

if (this.status === REJECTED) {
// 如果失败的then中有报错或者还返回一个promise直接向后传递即可
let x = onRejected(this.reason);
reject(x);
}

if (this.status === PENDING) {
this.onResolvedCallbacks.push(() => {
try {
let x = onFulfilled(this.value);
resolvePromise(newPromise, x, resolve, reject);
} catch(err) {
reject(err);
}
})
this.onRejectedCallbacks.push(() => {
let x = onRejected(this.reason);
reject(x);
})
}
})
})
return newPromise;
}

(2)如果then中执行后返回的还是一个promise

定义resolvePromise 函数来分情况处理then中返回的结果

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
const resolvePromise = (promise2, x, resolve, reject) => {
// 处理x的类型来决定下次then的状态是resolve还是reject
// promise2 === x的情况就相当于
// new Promise(resolve => resolve(1)).then(res => a1);
if (promise2 === x) {
return reject(new TypeError(`Chaining cycle detected for promise #<Promise>`));
}
let called = false;
// 判断x是不是一个普通函数
if (typeof x === 'object' && x !== null || typeof x === 'function') {
// 判断是否有then方法来判断是不是promise
try {
let then = x.then;
if (typeof then === 'function') {
// 是promise情况 使用then.call来执行x.then方法是为了避免有的对象写的只能获取一次。
// x.then需要再获取一次 而then.call是上次的缓存
then.call(x, y => {
// 参数可能还是promise需要递归
// .then(res => new Promise(resolve => resolve(new Promise..)))
resolvePromise(promise2, y, resolve, reject);
}, r => {
if (called) return; // 防止多次调用
called = true;
reject(r)
})
} else { // [1,2,3] {a:1}
resolve(x);
}
} catch(err) {
if (called) return; // 防止多次调用
called = true;
reject(err);
}
} else {
// 不是对象或者函数 普通值
resolve(x);
}
}

(3)返回值为promise

如果then中返回promise,也是需要等待这个新的promise执行完毕。直到返回一个resolve()为普通值的promise为止。

1
2
3
4
5
6
7
8
9
10
11
12
13
new Promise(resolve => resolve(1)).then(res => {
return new Promise(resolve => resolve(res))
}).then(res => {console.log(2)});

// 所以return 一个new promise,也是要先调用它的then方法返回一个新的promise
// 返回的新的promise继续then讲返回值向后抛
// 和resolve(Promise...) 一样 都是相当于加了2个then
new Promise(resolve => resolve(1))
.then(res => res)
.then(res => res).then(res => res) // 这两个就相当于新增的2个
.then(res => {
console.log(2)
});

如果promise当作resolve()的参数或者在then中直接返回。则相当于多加了2次then

2. Promise.resolve() 和 Promise.reject()

1
2
3
Promise.resolve('foo')
// 等价于
new Promise(resolve => resolve('foo'));

但是参数是分4种情况的:

(1)参数是一个 Promise 实例

如果参数是 Promise 实例,那么Promise.resolve将不做任何修改、原封不动地返回这个实例。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
// resolve()参数还是promise则相当于多加两个then
const p = new Promise(resovle => setTimeout(resovle));
new Promise(resolve => resolve(p)).then(() => {
console.log("3");
});
p.then(() => {
console.log("1");
}).then(() => {
console.log("2");
});
// 1 2 3

// 而如果Promise.resolve() 参数中的Promise则是直接替换
const p = new Promise(resovle => setTimeout(resovle));
Promise.resolve(p).then(() => {
console.log("3");
});
p.then(() => {
console.log("1");
}).then(() => {
console.log("2");
});
// 3 1 2

(2)参数是一个thenable对象

thenable对象指的是具有then方法的对象,比如下面这个对象。

1
2
3
4
5
let thenable = {
then: function(resolve, reject) {
resolve(42);
}
};

Promise.resolve方法会将这个对象转为 Promise 对象,然后就立即执行thenable对象的then方法。

1
2
3
4
5
6
7
8
9
10
let thenable = {
then: function(resolve, reject) {
resolve(42);
}
};

let p1 = Promise.resolve(thenable);
p1.then(function(value) {
console.log(value); // 42
});

上面代码中,thenable对象的then方法执行后,对象p1的状态就变为resolved,从而立即执行最后那个then方法指定的回调函数,输出 42。

(3)参数不是具有then方法的对象,或根本就不是对象

如果参数是一个原始值,或者是一个不具有then方法的对象,则Promise.resolve方法返回一个新的 Promise 对象,状态为resolved。

1
2
3
4
5
6
const p = Promise.resolve('Hello');

p.then(function (s){
console.log(s)
});
// Hello

等价于new Promise(resolve => resolve(‘Hello’));

(4)不带有任何参数

Promise.resolve()方法允许调用时不带参数,直接返回一个resolved状态的 Promise 对象。
所以,如果希望得到一个 Promise 对象,比较方便的方法就是直接调用Promise.resolve()方法。

1
2
3
4
5
const p = Promise.resolve();

p.then(function (res) {
// res undefined
});

上面代码的变量p就是一个 Promise 对象。

支持一下
扫一扫,支持superkimi
  • 微信扫一扫
  • 支付宝扫一扫