当我了解微任务和Promise时,遇到了一种我不了解的行为 [英] when I learned about microtask and Promise , I came across a behavior I don't understand
问题描述
我没有在then()回调中返回任何内容,我认为输出应该是1 5 7 2 6 3 4,但是结果是1 2 5 3 6 7 4,谁可以告诉我原因
I didn't return something in then() callback, In my opinion the output should be 1 5 7 2 6 3 4,but the result is 1 2 5 3 6 7 4, who can tell me why
Promise.resolve().then(function() {
console.log('promise1');
Promise.resolve().then(() => {
console.log('promise2')
Promise.resolve().then(() => {
console.log('promise3')
Promise.resolve().then(() => {
console.log('promise4')
})
})
})
}).then(function() {
console.log('promise5');
Promise.resolve().then(() => {
console.log('promise6')
})
}).then(() => {
console.log('promise7')
})
推荐答案
好的,这很冗长.与其他人相反,我会说 console.log
调用的执行顺序在这里是完全确定的.异步代码并不一定总是这种情况,但是当没有任何真实的"代码时,异步代码便会出现这种情况.异步代码正在发生,但仍然经常发生.
Alright, this will be very verbose. Contrary to others, i'll claim, that the execution order for the console.log
calls is completely deterministic here. This doesn't always have to be the case with async code, but when there isn't any "real" async code happening, it still often is.
为清楚起见,代码编号为
Code numbered for clarity:
01 Promise.resolve().then(function() {
02 console.log('promise1');
03
04 Promise.resolve().then(() => {
05 console.log('promise2')
06
07 Promise.resolve().then(() => {
08 console.log('promise3')
09
10 Promise.resolve().then(() => {
11 console.log('promise4')
12 })
13 })
14 })
15 }).then(function() {
16 console.log('promise5');
17
18 Promise.resolve().then(() => {
19 console.log('promise6')
20 })
21 }).then(() => {
22 console.log('promise7')
23 })
提醒:Javascript是单线程的,只能同时运行一个.
Reminder: Javascript is single-threaded, only one can run at the same time.
在下面,每个步骤都是代码执行,直到上下文被释放为止,再加上由于函数返回而导致的Promise解析.某些调用被省略了(例如 Promise.resolve()
),因为这很明显,会发生什么.
In the following, each step is code execution until the context is released, plus promise resolving because of the function returning. Some calls are omitted (e.g. Promise.resolve()
), because it's kind of obvious, what happens.
在每个步骤的最后,我将列出当前队列以及已经执行的 comment.log
调用.由于每个函数都以 console.log
调用开头,并且具有唯一的编号,因此我也将使用它们作为函数的名称.
At the end of each step, i'll list the current queue, and already executed comment.log
calls. As every function begins with a console.log
call, with a unique number, i'll use those as names for the functions as well.
注意:当函数结束时,该函数反过来解决了一个承诺,该承诺具有空的 [[PromiseFulfillReactions]]
,因为它并不重要,所以我不会提及它.
Note: When a function ends, which in turn resolves a promise, which has empty [[PromiseFulfillReactions]]
, i won't mention it, as it's not important.
程序开始运行...
-
01 Promise.resolve().then(function(){
被调用并排队1
-
15}).then(function(){
在未解决的承诺上被调用(从第1行的then
),等待其解决 -
21}).then(()=> {
在未解决的promise上被调用(来自第15行的then
),等待它解决
01 Promise.resolve().then(function() {
is called and enqueues1
15 }).then(function() {
is called on an unresolved promise (from thethen
in line 1), wait for it to resolve21 }).then(() => {
is called on an unresolved promise (from thethen
in line 15), wait for it to resolve
排队的任务: [1]
已执行的日志: []
-
02 console.log('promise1');
执行 -
04 Promise.resolve().then(()=> {
被调用并排队2
- 返回非对象
undefined
(肯定不是然后就可以,不是承诺),导致解决了第1行中从then
返回的承诺.turn导致执行其[[PromiseFulfillReactions]]
.唯一增加的反应是来自15}).then(function(){
(请参见上文).这使5
入队.
02 console.log('promise1');
executes04 Promise.resolve().then(() => {
is called and enqueues2
- Returning
undefined
, a non-object (certainly not then-able, not a promise), causes resolving of the promise returned fromthen
in line 1, which in turn causes its[[PromiseFulfillReactions]]
to be performed. The only added reaction is from15 }).then(function() {
(see above). This enqueues5
.
排队的任务: [2,5]
已执行的日志: [1]
-
05 console.log('promise2')
执行 -
07 Promise.resolve().then(()=> {
被调用并排队3
05 console.log('promise2')
executes07 Promise.resolve().then(() => {
is called and enqueues3
排队的任务: [5,3]
已执行的日志: [1、2]
-
16 console.log('promise5');
执行 -
18 Promise.resolve().then(()=> {
被调用并排队6
与上面类似, - Returning解决了从
15}返回的promise.then(function(){
,因此执行了[[PromiseFulfillReactions]]
.排队7
16 console.log('promise5');
executes18 Promise.resolve().then(() => {
is called and enqueues6
- Returning, similar to above, resolves the promise returned from
15 }).then(function() {
, so its[[PromiseFulfillReactions]]
are performed. This enqueues7
排队的任务: [3,6,7]
已执行的日志: [1、2、5]
-
08 console.log('promise3')
执行 -
10 Promise.resolve().then(()=> {
被调用并排队4
08 console.log('promise3')
executes10 Promise.resolve().then(() => {
is called and enqueues4
排队的任务: [6、7、4]
已执行的日志: [1、2、5、3]
为完成起见,我将添加最后的步骤,但是从这里开始很简单.
I'll add the last steps for completion's sake, but from here it's very straight forward.
-
19 console.log('promise6')
已执行
排队的任务: [7,4]
已执行的日志: [1、2、5、3、6]
-
22 console.log('promise7')
已执行
排队的任务: [4]
已执行的日志: [1、2、5、3、6、7]
-
11 console.log('promise4')
已执行
排队的任务: []
空!
已执行的日志: [1、2、5、3、6、7、4]
程序终止.
这篇关于当我了解微任务和Promise时,遇到了一种我不了解的行为的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!