详解promise、async和await的执行顺序
1、题目和答案
一道题题目:下面这段promise、async和await代码,请问控制台打印的顺序?
async function async1(){
console.log('async1 start')
await async2()
console.log('async1 end')
}
async function async2(){
console.log('async2')
}
console.log('script start')
setTimeout(function(){
console.log('setTimeout')
},0)
async1();
new Promise(function(resolve){
console.log('promise1')
resolve();
}).then(function(){
console.log('promise2')
})
console.log('script end')
上述,在Chrome 66和node v10中,正确输出是:
script start
async1 start
async2
promise1
script end
promise2
async1 end
setTimeout
2、知识点
显然,这考察的是js中的事件循环和回调队列。注意以下几点:
Promise优先于setTimeout宏任务。所以,setTimeout回调会在最后执行。Promise一旦被定义,就会立即执行。Promise的reject和resolve是异步执行的回调。所以,resolve()会被放到回调队列中,在主函数执行完和setTimeout前调用。await执行完后,会让出线程。async标记的函数会返回一个Promise对象
3、 难点
最令人困惑的,就是
async1 end在promise2之后输出
在函数async1中,执行promise(由于async2是async标记的函数,所以默认返回promise对象)会发现resolve(),然后放入回调队列。
接着执行下方的new Promise中的resolve()输出promise2,再回来输出async1 end。
其中,async1函数可以写成以下方式(便于理解):
async function async1(){
console.log('async1 start')
async2().then( _ => {
console.log( 'async1 end ')
})
}
3、流程
console.log('script start')输出:script startsetTimeout被放在最后调用- 执行
async1函数,输出async1 start。然后,进入async2函数,输出async2,并返回Promise对象。回到async1,由于await,让出线程,async2函数返回的Promise放在回调队列。 - 新new了一个
Promise对象,输出promise1。其中的resolve()被放在回调队列。 console.log('script end')输出:script end- 执行回调队列中,
async1返回的Promise对象,对象产生的resolve被放入对调队列。这里不输出任何值。 - 执行回调队列中,下方
Promise显式声明的resolve,输出promise2。 - 执行回调队列中,由于
async1函数返回的promise对象的resolve,输出async1 end。 - 执行回调队列中,最后的
setTimeout,输出setTimeout - finish
4、参考
欢迎技术交流,引用请注明出处。
个人网站:godbmw.com
Github:godbmw
详解promise、async和await的执行顺序的更多相关文章
- async和await的执行顺序问题
说明 : 要了解执行顺序,所需要的知识是了解浏览器js运行机制,以及微任务和宏任务的先后顺序.如果你明白了宏任务.微任务,请往下看: async function async1 () { consol ...
- promise、async和await之执行顺序
async function async1(){ console.log('async1 start') await async2() console.log('async1 end') } asyn ...
- JS中的async/await的执行顺序详解
虽然大家知道async/await,但是很多人对这个方法中内部怎么执行的还不是很了解,本文是我看了一遍技术博客理解 JavaScript 的 async/await(如果对async/await不熟悉 ...
- setTimeout、Promise、Async/Await 的执行顺序
问题描述:以下这段代码的执行结果 async function async1() { console.log('async1 start'); await async2(); console.log( ...
- promise, async和await
最开始实现异步的方法:回调函数 method1(function(err, result) { if (err) { throw err; } method2(function(err, result ...
- ES系列之Promise async 和 await
概述 promise是异步编程的一种解决方案,比传统的解决方案—回调函数和事件—更合理更强大. 所谓的promise就是一个容器,里面保存着某个未来才会结束的事件(通常是一个异步操作的结果). Pro ...
- .net 关于Task.Run 和 Async await的执行顺序
一直捋不清楚用Task.Run异步的执行关系,网上找的些说明写得也有点复杂,所以自己做实验测一下. 直接上代码 这个是加await private static void TestFun() { Co ...
- JQuery中$.ajax()方法参数详解 及 async属性说明
url: 要求为String类型的参数,(默认为当前页地址)发送请求的地址. type: 要求为String类型的参数,请求方式(post或get)默认为get.注意其他http请求方法,例如put和 ...
- 道可道,非常道——详解promise
promise 出来已久,以前一直使用,没有仔细剖析原理,最近在复习es6的知识,写一下自己对于promise的理解. promise是es6的一种异步编程解决方案,避免频繁的回调函数,增强代码的可阅 ...
随机推荐
- 利用UML语言建模--以图书馆管理系统为例
一.基本信息 标题:利用UML语言建模--以图书馆管理系统为例 时间:2016 出版源:内蒙古科技与经济 领域分类:UML:RFID:图书馆:模型: 二.研究背景 问题定义:建立图书馆管理系统 难点: ...
- 关于调试WCF时引发的异常XmlException: Name cannot begin with the '<' character, hexadecimal value 0x3C” on Client Side
问题描述:在使用VS2015调试WCF时,偶遇抛出异常名称不能以“<”字符(十六进制0x3c)开头,平时运行时(不调试)没有问题的. 解决方法:检查后发现为了检查异常的位置,勾选了引发通用语言运 ...
- Variables and Arithmetic Expression
Notes from The C Programming Language A decimal point in a constant indicates that it is floating po ...
- firewall 和 iptables 常用命令
[参考文章]:Centos7 关闭防火墙 [参考文章]:Centos7 firewall防火墙常用配置 CentOS 7.0默认使用的是firewall作为防火墙,使用iptables必须重新设置一下 ...
- fast.ai(零)windows + pytorch 0.4
一.下载 git clone https://github.com/fastai/fastai.git 或者直接下载下来 二.安装pytorch 去官网安装建议安装即可 https://pytorch ...
- eclipse clean和build作用
由于eclipse的编译是基于时间戳的判断机制的. 因此当你按build all的时候有些eclipse认为时间戳没有改变的类不会被编译. 因此你可以先clean一下再编译.这个时候eclipse ...
- java 浅谈web系统当中的cookie和session会话机制
一 Cookie: 1. Cookie翻译为小甜饼,有一种特殊的味道.cookie主要用来在(浏览器)客户端做记号用的.Cookie不属于java,Cookie是一种通用的机制,属于HTTP协议的一部 ...
- 理解 Python 的执行方式,与字节码 bytecode 玩耍 (下)
上次写到,Python 的执行方式是把代码编译成bytecode(字节码)指令,然后由虚拟机来执行这些 bytecode 而 bytecode 长成这个样子: b'|\x00\x00d\x01\x0 ...
- web自动化测试---xpath方式定位页面元素
在实际应用中,如果存在多个相同元素,包括属性相同时,一般会选用这种方式,当然如果定位属性唯一的话,也是可以使用的,不过这种方式没有像id,tag,name等容易理解,下面讲下xpath定位元素的方法 ...
- C# datagridview分页功能
winform开发是或多或少都会接触datagridview控件,如果数据量大,那么必须使用分页功能,但是datagridview自身并没有分页,所以我们要自己实现.在网上搜了一些发现没有太适合自己的 ...