setTimeout(() => {
console.log(0)
})
new Promise(resolve => {
resolve(1)
Promise.resolve().then(t => {
console.log(2)
})
console.log(3)
})
.then(t => {
console.log(t)
})
console.log(4)
为什么是先输出 2 再输出 1?而不是先1再2?求大佬解答,感激不尽!
setTimeout(() => {
console.log(0)
})
new Promise(resolve => {
resolve(1)
Promise.resolve().then(t => {
console.log(2)
})
console.log(3)
})
.then(t => {
console.log(t)
})
console.log(4)
为什么是先输出 2 再输出 1?而不是先1再2?求大佬解答,感激不尽!
在resolve同步调用的情况下,这里的执行顺序和then()的顺序有关,和resolve()的顺序无关。
https://mp.weixin.qq.com/s/VIoUDWq9212WsXweyfH5ZA
这篇文章最后面的例子比你这个还复杂,解释也挺详细,可以看看。
这里涉及到JavaScript执行栈和消息队列的概念(自己先了解一下哈)。
另外还要了解Promise的实现原理。(你可以试着自己实现一个Promise,也有相关文章。但是模拟的时候也是用setTimeout模拟,毕竟无法真正操作到js底层的执行栈和队列,细节效果可能有出入,但有助于理解原理)
下面是解释:
当promise.then(handle)执行后,这个promise进入等待状态,等有了结果,它会在js的消息队列中push一个任务(即这个handle)。等js的其他同步代码执行完了(即执行栈空闲了),再从队列中读取第一个任务handle,依次执行。
而如果promise.then(handle)执行后,这个promise是立刻(同步)返回结果的(同步返回结果或已有结果),它会立刻往队列中push(handle),等待执行,push的顺序影响执行顺序。
你题目中的两个.then(),都是同步返回结果的,所以then()的顺序就影响了push()的顺序,进而影响了执行顺序。与resolve()的顺序无关。
Promise.resolve().then(t => {console.log(2)})
相当于:
Promise.resolve(undefined).then(handle)。
已有了结果“undefined”,.then()的时候就立刻把handle给push到队列了。
xxx.then(t => { console.log(t) })
因为你直接resolve(1),相当于同步返回了结果1,此时也会立刻把handle给push到队列。
13 回答13k 阅读
7 回答2.1k 阅读
3 回答1.3k 阅读✓ 已解决
6 回答1.2k 阅读✓ 已解决
2 回答1.4k 阅读✓ 已解决
3 回答1.3k 阅读✓ 已解决
6 回答1.1k 阅读
一旦一个pormise有了结果,或者早已有了结果,他就会为它的回调产生一个微任务。如果在微任务执行期间微任务队列加入了新的微任务,会将新的微任务加入队列尾部,之后也会被执行。
当执行
resolve(1)
的时候,代码还没运行到then(t => {console.log(t)})
,这时候是没有回调的,所以这时候还是没有添加任何微任务的。接下来执行
Promise.resolve().then(t => {console.log(2)})
,为已有结果的内层Promise添加一个微任务,然后外层Promise执行.then(t => {console.log(t)})
,这时候外层Promise是属于早已有了结果,所以为这个回调添加一个微任务。输出2的微任务在输出1的微任务前面,所以是先输出 2 再输出 1