• 宏任务与微任务


    转自

    https://juejin.im/post/59e85eebf265da430d571f89

    导图要表达的内容用文字来表述的话:

    同步和异步任务分别进入不同的执行"场所",同步的进入主线程,异步的进入Event Table并注册函数。
    当指定的事情完成时,Event Table会将这个函数移入Event Queue。
    主线程内的任务执行完毕为空,会去Event Queue读取对应的函数,进入主线程执行。
    上述过程会不断重复,也就是常说的Event Loop(事件循环)。
    • macro-task(宏任务):
    包括整体代码script,setTimeout,setInterval
    • micro-task(微任务):
    Promise.then,Promise.catch, process.nextTick
    注意:
    1.
    promise是立即执行的,它创建的时候就会执行,不存在将promise推入微任务中的说法; resolve()是用来表示promise的状态为fullfilled,相当于只是定义了一个有状态的Promise,但是并没有调用它; promise调用then的前提是promise的状态为fullfilled; 只有promise调用then的时候,then里面的函数才会被推入微任务中

    2.
      script标签中的console.log()会立即执行

    分析:

    console.log('1');
    
    setTimeout(function() {
        console.log('2');
        process.nextTick(function() {
            console.log('3');
        })
        new Promise(function(resolve) {
            console.log('4');
            resolve();
        }).then(function() {
            console.log('5')
        })
    })
    process.nextTick(function() { console.log(
    '6'); })
    new Promise(function(resolve) { console.log('7'); resolve(); }).then(function() { console.log('8') }) setTimeout(function() { console.log('9'); process.nextTick(function() { console.log('10'); }) new Promise(function(resolve) { console.log('11'); resolve(); }).then(function() { console.log('12') }) })

    第一轮事件循环流程分析如下:

    • 整体script作为第一个宏任务进入主线程,遇到console.log,输出1。
    • 遇到setTimeout,其回调函数被分发到宏任务Event Queue中。我们暂且记为setTimeout1
    • 遇到process.nextTick(),其回调函数被分发到微任务Event Queue中。我们记为process1
    • 遇到Promisenew Promise直接执行,输出7。then被分发到微任务Event Queue中。我们记为then1
    • 又遇到了setTimeout,其回调函数被分发到宏任务Event Queue中,我们记为setTimeout2
    宏任务Event Queue微任务Event Queue
    setTimeout1 process1
    setTimeout2 then1
    • 上表是第一轮事件循环宏任务结束时各Event Queue的情况,此时已经输出了1和7。

    • 我们发现了process1then1两个微任务。

    • 执行process1,输出6。
    • 执行then1,输出8。

    好了,第一轮事件循环正式结束,这一轮的结果是输出1,7,6,8。

    那么第二轮事件循环从setTimeout1宏任务开始:

    • 首先输出2。接下来遇到了process.nextTick(),同样将其分发到微任务Event Queue中,记为process2new Promise立即执行输出4,then也分发到微任务Event Queue中,记为then2
    宏任务Event Queue微任务Event Queue
    setTimeout2 process2
      then2
    • 第二轮事件循环宏任务结束,我们发现有process2then2两个微任务可以执行。
    • 输出3。
    • 输出5。
    • 第二轮事件循环结束,第二轮输出2,4,3,5。
    • 第三轮事件循环开始,此时只剩setTimeout2了,执行。
    • 直接输出9。
    • process.nextTick()分发到微任务Event Queue中。记为process3
    • 直接执行new Promise,输出11。
    • then分发到微任务Event Queue中,记为then3
    宏任务Event Queue微任务Event Queue
      process3
      then3
    • 第三轮事件循环宏任务执行结束,执行两个微任务process3then3
    • 输出10。
    • 输出12。
    • 第三轮事件循环结束,第三轮输出9,11,10,12。

    整段代码,共进行了三次事件循环,完整的输出为1,7,6,8,2,4,3,5,9,11,10,12。
    (请注意,node环境下的事件监听依赖libuv与前端环境不完全相同,输出顺序可能会有误差)

  • 相关阅读:
    网页截图软件
    JavaScript的写类方式(3)
    XMLHttpRequest与script对比
    JavaScript的写类方式(5)
    Java方法传值和传引用
    变量的显示/隐式声明
    用递归实现十进制数转换N进制
    Javascript中克隆一个数组
    JavaScript1.6数组新特性和JQuery的几个工具方法
    HTML P不能包含块级元素(包括自身)
  • 原文地址:https://www.cnblogs.com/SRH151219/p/11164201.html
Copyright © 2020-2023  润新知