当前位置:首页 > 日记 > 正文

Js中async/await的执行顺序详解

Js中async/await的执行顺序详解

前言

虽然大家知道async/await,但是很多人对这个方法中内部怎么执行的还不是很了解,本文是我看了一遍技术博客理解 JavaScript 的 async/await(如果对async/await不熟悉可以先看下这篇文章)后拓展了一下,我理了一下await之后js的执行顺序,希望可以给别人解疑答惑,先简单介绍一下async/await。

  • async/await 是一种编写异步代码的新方法。之前异步代码的方案是回调和 promise。
  • async/await 是建立在 promise 的基础上。
  • async/await 像 promise 一样,也是非阻塞的。
  • async/await 让异步代码看起来、表现起来更像同步代码。这正是其威力所在。

async怎么处理返回值

async function testAsync() { return "hello async";}let result = testAsync();console.log(result)

输出结果:

Promise {[[PromiseStatus]]: "resolved", [[PromiseValue]]: "hello async"}

从结果中可以看到async函数返回的是一个promise对象,如果在函数中 return 一个直接量,async 会把这个直接量通过 Promise.resolve() 封装成 Promise 对象。

如果asyn函数没有返回值

async function testAsync1() { console.log("hello async");}let result1 = testAsync1();console.log(result1);

结果

hello asyncPromise {[[PromiseStatus]]: "resolved", [[PromiseValue]]: undefined}

结果返回Promise.resolve(undefined)

await做了什么处理

从字面意思上看await就是等待,await 等待的是一个表达式,这个表达式的返回值可以是一个promise对象也可以是其他值。

很多人以为await会一直等待之后的表达式执行完之后才会继续执行后面的代码,实际上await是一个让出线程的标志。await后面的函数会先执行一遍,然后就会跳出整个async函数来执行后面js栈(后面会详述)的代码。等本轮事件循环执行完了之后又会跳回到async函数中等待await

后面表达式的返回值,如果返回值为非promise则继续执行async函数后面的代码,否则将返回的promise放入promise队列(Promise的Job Queue)

async/await 执行顺序

先看一个例子

function testSometing() { console.log("执行testSometing"); return "testSometing";}async function testAsync() { console.log("执行testAsync"); return Promise.resolve("hello async");}async function test() { console.log("test start..."); const v1 = await testSometing();//关键点1 console.log(v1); const v2 = await testAsync(); console.log(v2); console.log(v1, v2);}test();var promise = new Promise((resolve)=> { console.log("promise start.."); resolve("promise");});//关键点2promise.then((val)=> console.log(val));console.log("test end...")

输出结果:

test start...执行testSometingpromise start..test end...testSometing执行testAsyncpromisehello asynctestSometing hello async

当test函数执行到

const v1 = await testSometing();

的时候,会先执行testSometing这个函数打印出“执行testSometing”的字符串,然后因为await会让出线程就会区执行后面的

var promise = new Promise((resolve)=> { console.log("promisestart.."); resolve("promise");});//关键点2

然后打印出“promise start..”接下来会把返回的这promise放入promise队列(Promise的Job Queue),继续执行打印“test end...”,等本轮事件循环执行结束后,又会跳回到async函数中(test函数),等待之前await 后面表达式的返回值,因为testSometing 不是async函数,所以返回的是一个字符串“testSometing”,test函数继续执行,执行到

const v2 = await testAsync();

和之前一样又会跳出test函数,执行后续代码,此时事件循环就到了promise的队列,执行promise.then((val)=> console.log(val));then后面的语句,之后和前面一样又跳回到test函数继续执行。

这个就是在async/await 函数之后js的执行顺序,我们再看一个列子把testSometing函数前面加上async

async function testSometing() { console.log("执行testSometing"); return "testSometing";}async function testAsync() { console.log("执行testAsync"); return Promise.resolve("hello async");}async function test() { console.log("test start..."); const v1 = await testSometing(); console.log(v1); const v2 = await testAsync(); console.log(v2); console.log(v1, v2);}test();var promise = new Promise((resolve)=> { console.log("promise start.."); resolve("promise");});//3promise.then((val)=> console.log(val));console.log("test end...")

输出结果:

test start...执行testSometingpromise start..test end...promisetestSometing执行testAsynchello asynctestSometing hello async

和上一个例子比较发现promise.then((val)=> console.log(val));先与console.log(v1);执行了,原因是因为现在testSometing函数加了async,返回的是一个Promise对象要要等它resolve,所以将当前Promise推入队列,所以会继续跳出test函数执行后续代码。之后就开始执行promise的任务队列了,所以先执行了promise.then((val)=> console.log(val));因为这个Promise对象先推入队列;

总结

写到这里大家应该已经清楚了使用async/await进行异步操作时js的执行顺序,在研究过程中还发现了js的任务队列执行顺序的问题,就下次再述。如果大家对有什么意见或建议可以指出。本篇是我第一次发布文章,希望大家不吝赐教。

好了,以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作能带来一定的帮助,如果有疑问大家可以留言交流,谢谢大家对的支持。

相关文章

JS设置随机出现2个数字的实例代码

JS设置随机出现2个数字的实例代码

设置,实例代码,数字,电脑软件,JS,1和2 随机出现<script type="text/javascript"> $(function(){ if (Math.random()>0.5) { console.log("1"); }else{ console.log("2"); } }); </script> PS:JS…

ES6 javascript中class类的get与se

ES6 javascript中class类的get与se

实例分析,电脑软件,javascript,set,class,本文实例讲述了ES6 javascript中class类的get与set用法。分享给大家供大家参考,具体如下:与 ES5 一样, 在 Class 内部可以使用get和set关键字, 对某个属性设置存值函数和取值函数, 拦截该属性的存取行为…

浪漫爱情一男一女情侣签名

浪漫爱情一男一女情侣签名

一女,浪漫爱情,情侣,热门,经典,  情侣签名时刻透露着甜蜜浪漫的气息,展现着浪漫爱情,下面来看看浪漫爱情一男一女情侣签名。情侣签名浪漫爱情一男一女【经典篇】世界这么小,我们就这样遇见世界这么大,分开就很难再见我的每场梦里有你才甜蜜我…

js以及jquery实现手风琴效果

js以及jquery实现手风琴效果

手风琴,效果,电脑软件,js,jquery,最近又复习了jQuery的知识,既然jQuery是javascript的一个库。jQuery能做到的事情javascript也能做到。因此用这两种方法实现了图片手风琴效果。 按照惯例,还是上代码吧,因为代码里有我的注释也就相当于解释了!(…

Nodejs 复制文件/文件夹的方法

Nodejs 复制文件/文件夹的方法

方法,复制文件,电脑软件,Nodejs,1.使用fs复制文件使用fs对象的readFileSync,writeFileSync方法进行读写操作复制cp.jsfunction copyIt(from, to) { fs.writeFileSync(to, fs.readFileSync(from)); //fs.createReadStream(src).pipe(fs.crea…

PS怎么把胡歌的转换成手绘素描?

PS怎么把胡歌的转换成手绘素描?

素描,转换成,手绘,电脑软件,PS,教大家如何把胡歌的照片制作素描效果,方法简单,大部分素描效果都是用这种方法,推荐给大家收藏学习了。软件名称:Adobe Photoshop 8.0 中文完整绿色破解版软件大小:150.1MB更新时间:2015-11-041、原素材(举个例子)2、…

微信小程序 参数传递实例代码

微信小程序 参数传递实例代码

实例代码,参数传递,程序,电脑软件,微信小,微信小程序 参数传递实例代码1、通过事件传递参数实例代码:<view data-id="103" bindtap="evenName"></view>Page({ evenName: function(e) { //获得点击事件传递的id console.log(e.target.d…

js中变量的连续赋值 | 实例讲解

js中变量的连续赋值 | 实例讲解

变量,连续赋值,实例,电脑软件,js,今天遇到了一个连续赋值的经典案例,网友们给出的答案也是五花八门,看起来有些繁琐,我也来说说自己的看法。下面就是这个经典案例:var a = {n: 1};var b = a;a.x = a = {n: 2};console.log(a);console.log(b);cons…

WPS演示中如何插入项目符号及调整

WPS演示中如何插入项目符号及调整

调整,项目,插入项目,符号,演示,  通常情况下我们都会用到项目符号或者编号在写演示文稿时罗列出一些重点,那么在wps演示中如何插入项目符号及编号。以下是小编为您带来的关于WPS演示中插入项目符号及调整项目符号,希望对您有所帮助。WPS演…

JS基于贪心算法解决背包问题示例

JS基于贪心算法解决背包问题示例

贪心算法,背包问题,示例,电脑软件,JS,本文实例讲述了JS基于贪心算法解决背包问题。分享给大家供大家参考,具体如下:贪心算法:在对问题求解时,总是做出在当前看来是最好的选择。也就是说,不从整体最优上加以考虑,他所做出的仅是在某种意义上的局部…

AI怎么给圆形添加模糊效果?

AI怎么给圆形添加模糊效果?

模糊,效果,电脑软件,AI,ai的图形想要显示的更加模糊,该怎么添加模糊效果呢?下面我们就来看看详细的教程。软件名称:Adobe Illustrator CS6 (AI cs6) 精简绿色中文版(32位+64位)软件大小:205MB更新时间:2014-05-111、为了清晰说明,此例中以一个圆…

excel 函数不显示计算结果的解决教

excel 函数不显示计算结果的解决教

函数,显示,教程,计算,电脑软件,  Excel中函数计算过后不显示计算结果具体该如何解决呢?下面是由小编分享的excel 函数不显示计算结果的解决教程,以供大家阅读和学习。excel 函数不显示计算结果的解决教程不显示结果解决步骤1:输入后显示了…