博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
异步执行顺序
阅读量:5948 次
发布时间:2019-06-19

本文共 2624 字,大约阅读时间需要 8 分钟。

异步执行顺序

任务队列

JavaScript通过任务队列管理所有异步任务,而任务队列还可以细分为MacroTask Queue和MicoTask Queue两类。

MacroTask Queue

MacroTask Queue(宏任务队列)主要包括setTimeout, setInterval, setImmediate, requestAnimationFrame, UI rendeing, NodeJS中的`I/O等。

MicroTask Queue

MicroTask Queue(微任务队列)主要包括两类:

1.独立回调microTask:如Promise,其成功/失败回调函数相互独立;

2.复合回调microTask:如 Object.observe, MutationObserver 和NodeJs中的 process.nextTick ,不同状态回调在同一函数体;

MacroTask和MicroTask

JavaScript将异步任务分为MacroTask和MicroTask,那么它们区别何在呢?

  1. 依次执行同步代码直至执行完毕;
  2. 检查MacroTask队列,若有触发的异步任务,则取第一个并调用其事件处理函数,然后跳至第三步,若没有需处理的异步任务,则直接跳至第三步;
  3. 检查MicroTask队列,然后执行所有已触发的异步任务,依次执行事件处理函数,直至执行完毕,然后跳至第二步,若没有需处理的异步任务中,则直接返回第二步,依次执行后续步骤;
  4. 最后返回第二步,继续检查MacroTask队列,依次执行后续步骤;
  5. 如此往复,若所有异步任务处理完成,则结束;

promise、setTimeout、async的先后执行顺序

准则:

1.先执行同步代码,遇到异步代码就先加入队列,然后按入队顺序执行异步代码,最后执行setTimeout队列的代码2.setTimeout的任务队列优先级低于promise队列,setTimeout的队列与promise不是一个队列3.setTimeout有默认4ms的延迟,所以不会立即执行,而是会进入宏队列4.await会让出当前线程,将后面的代码加到任务队列中,然后继续执行test()函数后面的同步代码复制代码
async function async1() {                                console.log("async1 start");  //(2)                             await  async2();                                 console.log("async1 end");   //(7)                     }                         async  function async2() {                               console.log( 'async2');   //(3)                      }                        console.log("script start");  //(1)                       setTimeout(function () {                                 console.log("settimeout");  //(8)                       },0);                         async1();                         new Promise(function (resolve) {                                console.log("promise1");   //(4)                              resolve();                         }).then(function () {                                 console.log("promise2");    //(6)                     });                         console.log('script end');//(5)复制代码
解析:先按顺序执行同步代码  从‘script start‘开始,执行到setTimeout函数时,将其回调函数加入队列(此队列与promise队列不是同一个队列,执行的优先级低于promise)。然后调用async1()方法,await async2();//执行这一句后,输出async2后,await会让出当前线程,将后面的代码加到任务队列中,然后继续执行test()函数后面的同步代码继续执行创建promise对象里面的代码属于同步代码,promise的异步性体现在then与catch处,所以promise1被输出,然后将then函数的代码加入队列,继续执行同步代码,输出script end。至此同步代码执行完毕。开始从队列中调取任务执行,由于刚刚提到过,setTimeout的任务队列优先级低于promise队列,所以首先执行promise队列的第一个任务,因为在async函数中有await表达式,会使async函数暂停执行,等待表达式中的 Promise 解析完成后继续执行 async 函数并返回解决结果。所以先执行then方法的部分,输出promise2,然后执行async1中await后面的代码,输出async1 end。。最后promise队列中任务执行完毕,再执行setTimeout的任务队列,输出settimeout。setTimeout(fn,0)的含义是指某个任务在主线程最早可得的空闲时间执行。它在“任务队列”的尾部添加一个事件,因此要等到同步任务和“任务队列”现有的时间处理完才会得到执行。复制代码

仅用于个人整理,参考:

转载于:https://juejin.im/post/5ca33c626fb9a05e181de58d

你可能感兴趣的文章
【Hadoop学习】HDFS基本原理
查看>>
关于解决IE8以下版本获取DOM节点的方法
查看>>
vue学习笔记(二)
查看>>
Flask四之模板
查看>>
要不, 我们从右往左书写数组?
查看>>
我的面试准备过程--LeetCode(更新中)
查看>>
【145天】尚学堂高淇Java300集视频精华笔记(103-104)
查看>>
如何在 React Native 中写一个自定义模块
查看>>
SegmentFault 2017 年社区周报 Vol.5
查看>>
JS用原型对象写的贪吃蛇,很粗糙的代码
查看>>
mac安装consul
查看>>
JavaScript深入之bind的模拟实现
查看>>
Learning Notes - Understanding the Weird Parts of JavaScript
查看>>
SegmentFault 2017 年社区周报 Vol.4
查看>>
两种方式javascript实现图片预览
查看>>
数据结构面试 之 单链表是否有环及环入口点 附有最详细明了的图解
查看>>
RancherOS v0.8.0发布:支持离线安装,更佳部署体验
查看>>
AI+社交,快手商业化落地之道
查看>>
Microsoft Graph:连接每个应用都需要的基础数据
查看>>
Latex格式html文件转换pdf和docx文档
查看>>