先看个例子,参考[1]
new Promise((resolve, reject) => {
console.log("promise")
resolve()
})
.then(() => { // 执行.then的时候生成一个promise是给最后一个.then的
console.log("then1")
new Promise((resolve, reject) => {
console.log("then1promise")
resolve()
})
.then(() => {// 执行这个.then的时候,生成的promise是下面一个then的
console.log("then1then1")
})
.then(() => {
console.log("then1then2")
})
})
.then(() => {
// 这个
console.log("then2")
})
结果:
promise
then1
then1promise
then1then1
then2
then1then2
问题:主要是疑惑then2在then1then1和then1then2之间
为了方便分析,列几个自己的理解,后面解释问题的时候方便。尤其是理论4和理论5
Promise是一个对象,他包含了
handlers.resolve = function (self, value) {
var result = tryCatch(getThen, value);
if (result.status === 'error') {
return handlers.reject(self, result.value);
}
var thenable = result.value;
if (thenable) {
safelyResolveThenable(self, thenable);
} else {
self.state = FULFILLED;
self.outcome = value;
var i = -1;
var len = self.queue.length;
while (++i < len) {
self.queue[i].callFulfilled(value);
}
}
return self;
};
参考[2],返回的Promise对象支持了链式调用
参考[2]返回值一节
(1)返回了一个值,那么 then 返回的 Promise 将会成为接受状态,并且将返回的值作为接受状态的回调函数的参数值。
(2)没有返回任何值,那么 then 返回的 Promise 将会成为接受状态,并且该接受状态的回调函数的参数值为 undefined。
(3)抛出一个错误,那么 then 返回的 Promise 将会成为拒绝状态,并且将抛出的错误作为拒绝状态的回调函数的参数值。
(4)返回一个已经是接受状态的 Promise,那么 then 返回的 Promise 也会成为接受状态,并且将那个 Promise 的接受状态的回调函数的参数值作为该被返回的Promise的接受状态回调函数的参数值。
(5)返回一个已经是拒绝状态的 Promise,那么 then 返回的 Promise 也会成为拒绝状态,并且将那个 Promise 的拒绝状态的回调函数的参数值作为该被返回的Promise的拒绝状态回调函数的参数值。
(6)返回一个未定状态(pending)的 Promise,那么 then 返回 Promise 的状态也是未定的,并且它的终态与那个 Promise 的终态相同;同时,它变为终态时调用的回调函数参数与那个 Promise 变为终态时的回调函数的参数是相同的。
参考[3],文章写的不错。大体讲明白了Promise和then的原理了。因为文章里面的截图不是很清楚,我还是去github上面翻源码出来看的舒服点,参考[4]
Promise.prototype.then = function (onFulfilled, onRejected) {
if (typeof onFulfilled !== 'function' && this.state === FULFILLED ||
typeof onRejected !== 'function' && this.state === REJECTED) {
return this;
}
var promise = new this.constructor(INTERNAL);
if (this.state !== PENDING) {
var resolver = this.state === FULFILLED ? onFulfilled : onRejected;
unwrap(promise, resolver, this.outcome);
} else {
this.queue.push(new QueueItem(promise, onFulfilled, onRejected));
}
return promise;
};
简单说明:
有了上面的这些理解,接下来分析一下一开始我不理解的打印结果。有些步骤简单明了,可能被我过了。当然,因为自己第一次去接触这个,所以步骤会写的比较繁琐一点~
如果例子中的new Promise改成,前面加一个return呢?
.then(() => { // 执行.then的时候生成一个promise是给最后一个.then的
console.log("then1")
new Promise((resolve, reject) => {
console.log("then1promise")
resolve()
})
// ===》改成
.then(() => { // 执行.then的时候生成一个promise是给最后一个.then的
console.log("then1")
// 就是这里的加了一个return
return new Promise((resolve, reject) => {
console.log("then1promise")
resolve()
})
根据[理论4],.then1函数体有了返回值,是一个Promise对象,而且是then1then2执行完返回的匿名Promise对象。所以只有等这个Promise对象resolve了之后,才会执行then2回调函数体的逻辑,所以’then2’最后才会打印。所以最终结果是:
promise
then1
then1promise
then1then1
then1then2
then2
[1]嵌套的promise执行顺序
[2]Promise.then
[3]从一道Promise执行顺序的题目看Promise实现
[4]lie
[5]Promise
[6]Promise 链式调用顺序引发的思考