当我了解微任务和Promise时,遇到了一种我不了解的行为 [英] when I learned about microtask and Promise , I came across a behavior I don't understand

查看:23
本文介绍了当我了解微任务和Promise时,遇到了一种我不了解的行为的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我没有在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 enqueues 1
  • 15 }).then(function() { is called on an unresolved promise (from the then in line 1), wait for it to resolve
  • 21 }).then(() => { is called on an unresolved promise (from the then 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'); executes
  • 04 Promise.resolve().then(() => { is called and enqueues 2
  • Returning undefined, a non-object (certainly not then-able, not a promise), causes resolving of the promise returned from then in line 1, which in turn causes its [[PromiseFulfillReactions]] to be performed. The only added reaction is from 15 }).then(function() { (see above). This enqueues 5.

排队的任务: [2,5]

已执行的日志: [1]

  • 05 console.log('promise2')执行
  • 07 Promise.resolve().then(()=> {被调用并排队 3
  • 05 console.log('promise2') executes
  • 07 Promise.resolve().then(() => { is called and enqueues 3

排队的任务: [5,3]

已执行的日志: [1、2]

  • 16 console.log('promise5'); 执行
  • 18 Promise.resolve().then(()=> {被调用并排队 6
  • 与上面类似,
  • Returning解决了从 15}返回的promise.then(function(){,因此执行了 [[PromiseFulfillReactions]] .排队 7
  • 16 console.log('promise5'); executes
  • 18 Promise.resolve().then(() => { is called and enqueues 6
  • Returning, similar to above, resolves the promise returned from 15 }).then(function() {, so its [[PromiseFulfillReactions]] are performed. This enqueues 7

排队的任务: [3,6,7]

已执行的日志: [1、2、5]

  • 08 console.log('promise3')执行
  • 10 Promise.resolve().then(()=> {被调用并排队 4
  • 08 console.log('promise3') executes
  • 10 Promise.resolve().then(() => { is called and enqueues 4

排队的任务: [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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆