setTimeout、Promise、Async/Await 的执行顺序
问题描述:以下这段代码的执行结果
async function async1() {
console.log('async1 start');
await async2();
console.log('asnyc1 end');
}
async function async2() {
console.log('async2');
}
console.log('script start');
setTimeout(() => {
console.log('setTimeOut');
}, 0);
async1();
new Promise(function (reslove) {
console.log('promise1');
reslove();
}).then(function () {
console.log('promise2');
})
console.log('script end');
解决问题:
要了解代码的执行顺序 必须先了解 JS的运行机制
Javascript
有一个main thread
主线程和call-stack
调用栈(执行栈),所有的任务都会被放到调用栈等待主线程执行。- JS调用栈采用的是后进先出的规则,当函数执行的时候,会被添加到栈的顶部,当执行栈执行完成后,就会从栈顶移出,直到栈内被清空。
Javascript
单线程任务被分为同步任务和异步任务,同步任务会在调用栈中按照顺序等待主线程依次执行,异步任务会在异步任务有了结果后,将注册的回调函数放入任务队列中等待主线程空闲的时候(调用栈被清空),被读取到栈内等待主线程的执行。
在JavaScript
中,任务被分为两种,一种宏任务(MacroTask
),一种叫微任务(MicroTask
)。
MacroTask(宏任务)
script
全部代码、setTimeout
、setInterval
。
MicroTask(微任务)
Promise、await
每次单个宏任务执行完毕后,检查微任务队列是否为空,如果不为空的话,会按照先入先出的规则全部执行完微任务后,设置微任务队列为
null
,然后再执行宏任务,如此循环。- setTimeout属于宏任务
- Promise本身是同步的立即执行函数,Promise.then属于微任务
- async方法执行时,遇到await会立即执行表达式,表达式之后的代码放到微任务执行
下面我们就来运行代码
第一次执行:执行同步代码
Tasks(宏任务):run script、 setTimeout callback
Microtasks(微任务):await、Promise then
JS stack(执行栈): script
Log: script start、async1 start、async2、promise1、script end
第二次执行:执行宏任务后,检测到微任务队列中不为空、一次性执行完所有微任务
Tasks(宏任务):run script、 setTimeout callback
Microtasks(微任务):null
JS stack(执行栈): await、Promise then
Log: script start、async1 start、async2、promise1、script end、promise2、async1 end
第三次执行:当微任务队列中为空时,执行宏任务,执行setTimeout callback
,打印日志。
Tasks(宏任务):null Microtasks(微任务):null JS stack(执行栈):setTimeout callback
Log: script start、async1 start、async2、promise1、script end、promise2、async1 end、setTimeout
关于73以下版本和73版本的区别
- 在老版本版本以下,先执行
promise2
,再执行async1 end
。 - 在73及以上版本,先执行
async1 end
再执行promise2
。 - 具体资料可以查询 https://v8.js.cn/blog/fast-async/
于是我们就得到了这段代码的执行结果(70版本)
(73及以上版本执行结果为)
script start
async1 start
async2
promise1
script end
async1 end
promise2
setTimeout
setTimeout、Promise、Async/Await 的执行顺序的更多相关文章
- 一道题理解setTimeout,Promise,async/await以及宏任务与微任务
今天看到这样一道面试题: //请写出输出内容 async function async1() { console.log('async1 start'); await async2(); consol ...
- JS中的async/await的执行顺序详解
虽然大家知道async/await,但是很多人对这个方法中内部怎么执行的还不是很了解,本文是我看了一遍技术博客理解 JavaScript 的 async/await(如果对async/await不熟悉 ...
- ES6 class setTimeout promise async/await 测试Demo
class Person { async getVersion () { return new Promise((resolve, reject) => { setTimeout(functio ...
- .net 关于Task.Run 和 Async await的执行顺序
一直捋不清楚用Task.Run异步的执行关系,网上找的些说明写得也有点复杂,所以自己做实验测一下. 直接上代码 这个是加await private static void TestFun() { Co ...
- async await 的执行
async await的执行 注意:本次代码仅在 Chrome 73 下进行测试. start 不了解 async await 的,先去看阮一峰老师的文章async 函数. 先来看一道头条的面试题,这 ...
- 详解promise、async和await的执行顺序
1.题目和答案 一道题题目:下面这段promise.async和await代码,请问控制台打印的顺序? async function async1(){ console.log('async1 sta ...
- 理解 async/await 的执行
这是一篇简单的短文章,方便理解. 开局先丢官宣:sec-async-function-definitions 这个链接是对 await 的解释,解释了它的执行. await 的执行意味着(官宣巴拉巴拉 ...
- node.js async/await 继发执行与并发执行
async/await 继发执行与并发执行,看如何控制 两个异步函数 foo bar function foo() { return new Promise((resolve, reject) =&g ...
- vue使用技巧:Promise + async + await 解决组件间串行编程问题
业务场景描述 大家都通过互联网投递过简历,比如在智联.58.猎聘等平台.投递心仪的职位前一般都需要前提创建一份简历,简历编辑界面常规的布局最上面是用户的个人基本信息,如姓名.性别.年龄.名族等,接着是 ...
随机推荐
- 洛谷P3948 数据结构——题解
题目传送 感觉这道题秀了我一地的智商... 审题没审好,没确定带修改的操作中询问的次数<=1000,且max和min都是事先给好.不变的.想了半天线段树.分块,却忘了最基础的暴力. 写不出题时先 ...
- [design pattern](5) Factory Method
前言 在前面一章博主介绍了简单工厂模式(Simple Factory),接着上面的章节,今天博主就来介绍下工厂方法模式(Factory Method). 思考题 首先,让我们来思考下面的问题: 在上一 ...
- pyhton2与pyhton3切换
ubuntu中默认的Python版本是Python2.X,但是现在Python的最新版本是Python3.X. 那么怎么修改ubutun系统默认的Python解释器呢? 如果没有安装,则使用以下命令安 ...
- 使用collection查询集合属性
介绍resultMap中使用collection查询集合属性 业务需求,查询部门中的多个人员 public class Department { private Integer id; private ...
- PLSQL导出还原数据库
1 导出存储过程,触发器,序列等所有用户对象.(备份) 导出所有的表,存储过程,触发器,序列等所有的创建语句(.sql文件) 在PL/SQL Developer的菜单Tools(工具) => ...
- python3 以utf-8编码写文件
原来的 save = open('1.txt', 'w', 'utf8') 用下面的 save = codecs.open('1.txt', 'w', 'utf8')
- 阶段3 1.Mybatis_11.Mybatis的缓存_4 mybatis一对多实现延迟加载
改成单表查询 首先配置的是select.他需要配置的值是accountDao中的方法,查询所有的账户,但是必须有条件.根据用户的id column配置的是id.因为要用user表的id去关联查询 Ac ...
- 工具类分享之获取Request/Response工具类《RequestContextHolderUtil》
版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.csdn.net/aiyaya_/article/details/78975893前言在开发spring web项目时, ...
- 【ABAP系列】SAP ABAP 运算符
公众号:SAP Technical 本文作者:matinal 原文出处:http://www.cnblogs.com/SAPmatinal/ 原文链接:[ABAP系列]SAP ABAP 运算符 前 ...
- zip函数用于对列表对应元素打包成元组
zip() 函数用于将可迭代的对象作为参数,将对象中对应的元素打包成一个个元组,然后返回由这些元组组成的列表. 如果各个迭代器的元素个数不一致,则返回列表长度与最短的对象相同,利用 * 号操作符,可以 ...