Promise.resolve().then(() => {
console.log('start')
return Promise.resolve('end')
}).then(res => {
console.log(res)
})
Promise.resolve().then(() => {
console.log(1)
}).then(() => {
console.log(2)
}).then(() => {
console.log(3)
}).then(() => {
console.log(4)
}).then(() => {
console.log(5)
}).then(() => {
console.log(6)
})
这是刚从某网站偶然间看到的一道面试题,问打印输出的顺序。
原来全都是数字,为了方便描述我把两个Promise的打印区分开来了。
分开的顺序很好理解,一定是start end
和 1 2 3 4 5 6
但是把他们放到一起顺序我就有点吃不准,放到不同浏览器和vscode(虽然vscode好像也是用V8跑的)中跑了一下,输出顺序始终是start 1 2 3 end 4 5 6
让我很不理解。start
在1
之前是能理解的,如果是start 1 end 2 3 4 5 6
这样也是可以理解的,但是很奇怪的是end
为什么会在3
、4
之间。
想了一会儿突然想到把第一个Promise中的return删了,直接在.then()
里打印end
也就是下面代码这样会怎么样呢?
Promise.resolve().then(() => {
console.log('start')
Promise.resolve('end').then(res => {
console.log(res)
})
})
果然这次顺序变成了start 1 end 2 3 4 5 6
。
是否就是因为return消耗的额外的时间导致微任务队列额外又加入了console.log(2)
和console.log(3)
呢?
如果是这样这面试题也太坑了吧,不实际敲一下鬼知道return的时间够几个callback进入微任务队列啊,而且这实际已经和event loop没啥关系了吧,实际面试要是遇到这种出这种题目的公司是不是可以直接拉黑了?
关于这道题目衍生,因为实际应用中很少有这道题中的Promise,一般异步同时进行都是多个网络请求,这个时候微任务队列的顺序就和接口响应时间有关,顺序不固定。但是如果Promise中不涉及网络请求,代码一致且完整执行的情况下是否callback进入微任务队列的顺序与Promise进入微任务队列的顺序一致呢?换言之即下列代码,与任何外部情况无关,只要代码执行完毕输出顺序是否一定是1 6 2 7 3 8 4 9 5 10
呢?
Promise.resolve().then(() => {
console.log(1)
}).then(() => {
console.log(2)
}).then(() => {
console.log(3)
}).then(() => {
console.log(4)
}).then(() => {
console.log(5)
})
Promise.resolve().then(() => {
console.log(6)
}).then(() => {
console.log(7)
}).then(() => {
console.log(8)
}).then(() => {
console.log(9)
}).then(() => {
console.log(10)
})
之前也有过类似的疑问,可以看看这个哈,希望对你有所帮助https://www.zhihu.com/question/453677175/answer/2815817162