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.猎聘等平台.投递心仪的职位前一般都需要前提创建一份简历,简历编辑界面常规的布局最上面是用户的个人基本信息,如姓名.性别.年龄.名族等,接着是 ...
随机推荐
- Task的用法
创建任务 无返回值的方式 方式1: var t1 = new Task(() => TaskMethod("Task 1")); t1.Start(); Task.WaitA ...
- (53)LINUX应用编程和网络编程之八Linux网络基础
3.8.1.网络通信概述 3.8.1.1.从进程间通信说起:网络域套接字socket,网络通信其实就是位于网络中不同主机上面的2个进程之间的通信. 3.8.1.2.网络通信的层次 (1)硬件部分:网卡 ...
- 通过ecplise导入mysql的jar包时,右键找不到build path问题
当我们执行java连接数据库程序的时候,我们需要再我们的项目里导入mysql的jar包,这时,我们需要右键->build path进行导入,但是有时候我们右键的时候并没有出现build path ...
- localstorage sessionstorage cookie的区别
一.基本概念 Cookie cookie比较小,大小限制在4kb左右,是网景公司的前雇员 LouMontulli 在1993年3月的发明.它的主要用途有保存登录信息,比如你登录某个网站市场可以看到“记 ...
- HBase调优案例(一)——建表长时间等待最后失败
现象: 1.在HBase Shell里执行建表操作会等很久,最终失败: 2.通过代码侧进行建表同样不能成功. 原因排查: 1.查询HMaster日志,发现有接收到建表(create)的RPC请求: ...
- window.open传递多个参数
在前台使用var url = 'AddFiles.aspx?name=' + nm + '&id=' + id; window.open(url, "", "wi ...
- 如何让css与js分离
在 webpack 我们如何让 css 与 js 分离: 我们需要安装插件:extract-text-webpack-plugin 1. 用:npm 下载插件 npm install extract- ...
- java kryo序列化与反序列化
https://blog.csdn.net/lan12334321234/article/details/84907492 问题: https://blog.csdn.net/baidu_384041 ...
- 怎么用jira写bug
工具/原料 有网的电脑 方法/步骤1: 打开公司给的访问JIRA的链接,输入公司给你注册的账号和密码,点击登录 方法/步骤2: 点击JIRA主菜单上的“创建”,进入编辑bug界面 方法/步骤3: 项目 ...
- await Vue.nextTick() 的含义分析
概述 今天看别人的单元测试代码的时候碰到了一段代码 await Vue.nextTick(),初看起来不是很懂,后来通过查资料弄懂了,记录下来,供以后开发时参考,相信对其他人也有用. await Vu ...