当前位置: 首页 > article >正文

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");
async1();
console.log("script end");
// 输出顺序:
// script start
// async1 start
// async2
// script end
// async1 end

我不太理最后2个的输出顺序为什么不是先async1 end,再script end请详细解释一下

解答

你遇到的这个问题涉及到 JavaScript 的事件循环机制和 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");
async1();
console.log("script end");

事件循环和任务队列

JavaScript 是单线程的,执行任务有两种类型:

  1. 同步任务:这些任务会立即执行,直接进入主线程。
  2. 异步任务:这些任务(如 setTimeoutPromiseasync/await)不会立即执行,它们会在主线程空闲后通过事件循环执行。async/await 是基于 Promise 的,会将 await 后面的代码加入到微任务队列中。

微任务(Microtask)优先级比宏任务(Macrotask)高。

执行顺序解析

  1. console.log("script start"):这是同步任务,立即执行,输出:

    script start
    
  2. async1() 调用async1 是异步函数,它会立即执行到 await async2() 之前的同步代码。也就是 console.log("async1 start"),输出:

    async1 start
    
  3. await async2():当遇到 await 时,async1 的执行会暂停,直到 async2() 返回的 Promise 被解析(resolved)。但 async2() 是一个普通的异步函数,没有 await,它会立即执行 console.log("async2"),输出:

    async2
    

    这里,async2() 运行完后,没有返回 Promise,所以 await 被视为等待一个已经解决的 Promise。但即使是这样,await 后面的代码(console.log("async1 end"))会被放入微任务队列中,不会立即执行。

  4. console.log("script end"):这也是同步任务,会立即执行,输出:

    script end
    
  5. 微任务队列:同步任务执行完毕后,JavaScript 事件循环会检查微任务队列。在这里,await 后面的代码 console.log("async1 end") 会从微任务队列中取出执行,输出:

    async1 end
    

最终输出顺序

  • script start(同步任务)
  • async1 start(同步任务)
  • async2(同步任务)
  • script end(同步任务)
  • async1 end(微任务)

总结:await 后面的代码不会立即执行,而是进入微任务队列,等待主线程上的同步任务完成后才执行。所以,script end 会先输出,async1 end 在微任务队列中排队,最后执行。


http://www.kler.cn/a/301141.html

相关文章:

  • linux mysql 备份
  • 一个使用 Golang 编写的新一代网络爬虫框架,支持JS动态内容爬取
  • 通过外部链接启动 Flutter App(详细介绍及示例)
  • 【Rust自学】12.3. 重构 Pt.1:改善模块化
  • 组织切片配准(切割角度校正)
  • Java语言的正则表达式
  • h5页面使用antd-modal,怎么处理居中且自然
  • Flutter-底部选择弹窗(showModalBottomSheet)
  • Ubuntu系统使用Docker部署Jupyter Notebook并实现笔记云同步
  • Java 面试题:Java的垃圾收集算法 --xunznux
  • 算法岗/开发岗 实况
  • 不允许有程序员不知道这款AI代码扩写工具
  • 学会分析问题,画出分析图,解释问题过程,找出规律 ;整数数组分为左右2个部分,左边位奇数右边偶数
  • B端产品经理的流程设计思维
  • Selenium面试题(二)
  • 从自动化到智能化的研究
  • Vue邮件发送:如何有效集成邮件发送功能?
  • day20JS-axios数据通信
  • Java面试题·解释题·框架部分
  • FastGPT自定义插件的icon
  • Ubuntu系统Docker部署数据库管理工具DbGate并实现远程查询数据
  • Hash算法与Hash冲突
  • JS_分支结构
  • JavaWeb - Mybatis-Plus - 条件构造器
  • 【机器学习】高斯过程的基本概念和应用领域以及在python中的实例
  • vue原理分析(十)研究new Vue()中的initEvents