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

发布时间 - 2026-01-11 03:22:16    点击率:

前言

虽然大家知道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 async
Promise {[[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");});//关键点2
promise.then((val)=> console.log(val));

console.log("test end...")

输出结果:

test start...
执行testSometing
promise start..
test end...
testSometing
执行testAsync
promise
hello async
testSometing hello async

当test函数执行到

const v1 = await testSometing();

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

var promise = new Promise((resolve)=> { console.log("promise
start.."); 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");});//3
promise.then((val)=> console.log(val));

console.log("test end...")

输出结果:

test start...
执行testSometing
promise start..
test end...
promise
testSometing
执行testAsync
hello async
testSometing 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  # async  # await  # JS中async/await实现异步调用的方法  # JavaScript中的await/async的作用和用法  # 在JS循环中使用async/await的方法  # JS中的async与await怎么使用  # JS循环中正确使用async、await的姿势分享  # js异步之async和await实现同步写法  # JavaScript async/await的使用场景与规范  # 的是  # 返回值  # 又会  # 是一个  # 就会  # 一遍  # 列子  # 会把  # 这篇文章  # 跳回  # 先看  # 本轮  # 会先  # 有什么  # 是一种  # 是因为  # 好了  # 不吝赐教  # 基础上  # 才会 


相关栏目: 【 网站优化151355 】 【 网络推广146373 】 【 网络技术251813 】 【 AI营销90571


相关推荐: Win11应用商店下载慢怎么办 Win11更改DNS提速下载【修复】  Laravel Eloquent访问器与修改器是什么_Laravel Accessors & Mutators数据处理技巧  Win11搜索不到蓝牙耳机怎么办 Win11蓝牙驱动更新修复【详解】  如何快速搭建安全的FTP站点?  Laravel如何理解并使用服务容器(Service Container)_Laravel依赖注入与容器绑定说明  Microsoft Edge如何解决网页加载问题 Edge浏览器加载问题修复  Laravel用户密码怎么加密_Laravel Hash门面使用教程  Laravel如何使用.env文件管理环境变量?(最佳实践)  Laravel如何实现RSS订阅源功能_Laravel动态生成网站XML格式订阅内容【教程】  Laravel如何实现用户注册和登录?(Auth脚手架指南)  长沙企业网站制作哪家好,长沙水业集团官方网站?  Windows10电脑怎么设置虚拟光驱_Win10右键装载ISO镜像文件  专业商城网站制作公司有哪些,pi商城官网是哪个?  Laravel如何处理和验证JSON类型的数据库字段  百度输入法ai面板怎么关 百度输入法ai面板隐藏技巧  Android仿QQ列表左滑删除操作  如何在IIS中新建站点并解决端口绑定冲突?  Laravel如何使用API Resources格式化JSON响应_Laravel数据资源封装与格式化输出  教学论文网站制作软件有哪些,写论文用什么软件 ?  如何基于云服务器快速搭建网站及云盘系统?  高性能网站服务器配置指南:安全稳定与高效建站核心方案  php读取心率传感器数据怎么弄_php获取max30100的心率值【指南】  Laravel如何与Vue.js集成_Laravel + Vue前后端分离项目搭建指南  如何确保西部建站助手FTP传输的安全性?  怎么用AI帮你设计一套个性化的手机App图标?  魔方云NAT建站如何实现端口转发?  Laravel怎么自定义错误页面_Laravel修改404和500页面模板  如何在万网利用已有域名快速建站?  怎么制作一个起泡网,水泡粪全漏粪育肥舍冬季氨气超过25ppm,可以有哪些措施降低舍内氨气水平?  如何利用DOS批处理实现定时关机操作详解  如何快速搭建二级域名独立网站?  Laravel API路由如何设计_Laravel构建RESTful API的路由最佳实践  C语言设计一个闪闪的圣诞树  Java遍历集合的三种方式  Laravel如何处理文件下载请求?(Response示例)  Laravel怎么配置.env环境变量_Laravel生产环境敏感数据保护与读取【方法】  如何在Windows服务器上快速搭建网站?  详解ASP.NET 生成二维码实例(采用ThoughtWorks.QRCode和QrCode.Net两种方式)  bootstrap日历插件datetimepicker使用方法  Laravel项目结构怎么组织_大型Laravel应用的最佳目录结构实践  猪八戒网站制作视频,开发一个猪八戒网站,大约需要多少?或者自己请程序员,需要什么程序员,多少程序员能完成?  如何在新浪SAE免费搭建个人博客?  Laravel如何处理JSON字段_Eloquent原生JSON字段类型操作教程  phpredis提高消息队列的实时性方法(推荐)  微信公众帐号开发教程之图文消息全攻略  Linux网络带宽限制_tc配置实践解析【教程】  Laravel如何使用Blade组件和插槽?(Component代码示例)  Android使用GridView实现日历的简单功能  网页设计与网站制作内容,怎样注册网站?  jQuery validate插件功能与用法详解