zoukankan      html  css  js  c++  java
  • promise 及 setTimeout 执行顺序

    setTimeout(function() {
        console.log(1);
    }, 0);
    
    new Promise(function(res, rej) {
        res(2);
        console.log(0); 
    }).then(console.log);
    
    console.log(3);

    执行顺序如下:

    setTimeout 的任务会被排到队列尾部,同步任务执行结束后立即执行 setTimeout(即 console.log(1));

    而 promise 一旦建立,其中的任务就会立即执行(即 console.log(0));

    最外层的 console.log(3) 为同步任务,则按顺序执行;

    promise 中的 then 会等待 resolve 执行结束后即执行(即 res(2));

    所以执行后打印出来的顺序为:0、3、2、undefined、1

    微任务与宏任务

    console.log('script start')
    
    setTimeout(function() {
      console.log('setTimeout')
    }, 0)
    
    new Promise(resolve => {
      console.log('Promise')
      resolve()
    })
      .then(function() {
        console.log('promise1')
      })
      .then(function() {
        console.log('promise2')
      })
    
    console.log('script end')
    // script start => Promise => script end => promise1 => promise2 => setTimeout

    以上代码虽然 setTimeout 写在 Promise 之前,但是因为 Promise 属于微任务而 setTimeout 属于宏任务,所以会有以上的打印。

    微任务包括 process.nextTick ,promise ,Object.observe ,MutationObserver

    宏任务包括 script , setTimeout ,setInterval ,setImmediate ,I/O ,UI rendering

    很多人有个误区,认为微任务快于宏任务,其实是错误的。因为宏任务中包括了 script ,浏览器会先执行一个宏任务,接下来有异步代码的话就先执行微任务。

    所以正确的一次 Event loop 顺序是这样的

    1. 执行同步代码,这属于宏任务
    2. 执行栈为空,查询是否有微任务需要执行
    3. 执行所有微任务
    4. 必要的话渲染 UI
    5. 然后开始下一轮 Event loop,执行宏任务中的异步代码

    通过上述的 Event loop 顺序可知,如果宏任务中的异步代码有大量的计算并且需要操作 DOM 的话,为了更快的 界面响应,我们可以把操作 DOM 放入微任务中

  • 相关阅读:
    文件的操作
    encode,decode,str,bytes
    字符串操作
    suse12安装mysql8.16
    VMware配置共享磁盘安装RAC
    Linux过滤文本并显示过滤文字的上下文
    Linux服务器卸载mysql指南
    oracle 各版本各日志存放位置
    impdp按用户导入
    数据泵expdp定时备份
  • 原文地址:https://www.cnblogs.com/momo798/p/11719512.html
Copyright © 2011-2022 走看看