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

js中的promise、async/await 用法,详解async、await 语法糖,js中的宏任务和微任务(保姆级教程二)

前提:在学习 async、await 之前,需要提前了解 js 中的 同步异步任务、promise 等相关知识,可以参考之前的文章:点击查看

文章目录

    • 一、async、await 语法糖的基本认识
    • 二、根据案例理解 async、await
    • 三、promise、async、await综合案例

一、async、await 语法糖的基本认识

① async(异步):放在 function 前修饰

  • async 的作用:声明一个 function(也就是一个函数)是异步的

  • 在函数内 return,不管 return 的是什么,外部调用这个函数时,获取到的都是一个 Promise 对象(也就是说会对返回结果进行封装),需要通过 函数名().then 获取到 return

    也就是说:async 修饰的函数,只要有返回,就会返回一个 Promise 对象,如果在函数中 return 一个直接量,async 也会把这个直接量通过 Promise.resolve() 的方式封装成 Promise 对象。

② await(异步–等待):函数内有 await,必须要使用 async 修饰;有 aysnc 修饰的函数,函数内不一定非要有 await 代码;

  • await 的作用:等待一个异步方法执行完成。如果最终等待的值是成功的 Promise 对象,则会阻塞后面的代码(也就是:将 async 函数剩余任务推入到微任务队列);反之,不会;
  • await 会简化 then,直接得到 resolve 里面的数据

二、根据案例理解 async、await

① await + promise对象

function test() {return new Promise(((resolve, reject) => {//假装是你的异步任务:const isSuccess = trueif (isSuccess)resolve('任务2成功')elsereject('任务2失败')}))
}async function main() {//任务1,3,4是同步任务console.log('任务1')const data = await test();console.log(data)console.log('任务3')
}
main()
console.log("任务4")

分析:

  • 首先调用 main 函数,由于任务1,3,4是同步任务,本应该先执行,但是定义任务2 的 test 函数返回成功的 promise 对象,所以 await 处,就会将 async 函数剩余任务推入到微任务队列,所以先输出任务4,同步任务执行完之后,最后输出微任务队列中的内容。(并且 await 是直接拿到 resolve 中的值)

  • 假如返回失败的 promise 对象,则 剩余任务不会被推入微任务队列执行,它会返回 Promise.reject(err)

    外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

② await + 普通的值

async function main() {console.log('任务1')const data = await 2;console.log(data)console.log('任务3')
}
main()
console.log("任务4")

分析:它本质上是将其转化为 Promise.resolve(2),所以会返回一个成功的 promise 对象,也会将 async 函数剩余内容推入到微任务队列中等待执行。

③ await + 函数

function test1(){console.log("函数1")
}async function main() {//任务1,3,4是同步任务console.log('任务1')await test1()console.log('任务3')
}
main()
console.log("任务4")

分析:如果 await 右边是一个函数(不管这个函数有没有 async 修饰),它都会立刻执行这个函数,而且只有当这个函数执行结束后(即函数完成),才会将 async 剩余任务推入微任务队列。

三、promise、async、await综合案例

1、综合案例一:

async function async1() {console.log(1)await async2()console.log(2)
}const async2 = async () => {await (async () => {await (() => {console.log(3)})()console.log(4)})()
}const async3 = async () => {Promise.resolve().then(() => {console.log(6)})
}async1()
console.log(7)
async3()


分析代码前,需要:

1、先学习 js 中的立即执行函数 ----> 语法:(函数内容)()

其中() 就是代表立即执行的意思,表示这个函数立即执行,因为函数定义完之后,假如不调,是不会运行的,所以可以使用这个来立即执行函数,比如:

2、再学习 js 中的宏任务队列、微任务队列:异步任务分为微任务、宏任务,微任务优先级>宏任务。常见的微任务有:Promise.then.catch。常见的宏任务有:setTimeout()、setInterval()

再来分析代码:

  • 首先调用async1输出1,遇到await async2()函数,开始立即执行async2()函数,直到async2()函数完成,才将cl(2)推入微任务队列

  • 执行async2时,遇到第一个await,开始执行第一个await后面的函数(先将这个函数定义为A)(因为有 () 所以可以立即执行),函数A包括两部分:另一个函数、cl(4)。所以接着执行函数A中的内容,遇到第二个await,而且后面又跟着另一个函数(定义为B)(且也是立即执行),所以执行函数B,输出3。函数B执行完,于是将cl(4)推入微服务队列,由于cl(4)没执行,所以函数A也就没执行完,即async2函数没执行完。

    至此,微任务队列有:cl(4)

  • 开始执行输出cl(7)

  • 执行async3()函数,将cl(6)推入微任务队列。

    至此,微任务队列有:cl(4)、cl(6)

  • 同步任务完成,调用微任务队列任务,输出4,函数A执行完,也就是async2函数执行完,于是将cl2推入微任务队列

    至此,微任务队列有:cl(6)、cl(2)

  • 然后接着执行微任务队列:输出6、2

至此,关于 promise、async、await 讲解完毕!有啥问题欢迎评论,后续更新更精彩的文章!!!

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • vscode的C/C++环境配置和调试技巧
  • 基于Transformer机制的AI现阶段可能已达峰值
  • xss复现
  • WPF打印控件内容
  • 嵌入式linux系统镜像制作day2
  • 软件工程概述(上)
  • 关注自闭症儿童:走进他们孤独的世界
  • CentOS7安装流程步骤详细教程
  • 数学建模预测类—【多元线性回归】
  • 【ARM】Cortex-A72技术手册(1)
  • c语言---文件
  • SQL每日一练-0816
  • CSS的:current伪类:精准定位当前活动元素
  • Kali Linux网络问题解决与静态IP配置技巧
  • uniapp webview子页面向父页面发送数据和触发事件,重点在第3条!!!
  • 实现windows 窗体的自己画,网上摘抄的,学习了
  • [LeetCode] Wiggle Sort
  • 「前端早读君006」移动开发必备:那些玩转H5的小技巧
  • 【402天】跃迁之路——程序员高效学习方法论探索系列(实验阶段159-2018.03.14)...
  • JS变量作用域
  • Laravel核心解读--Facades
  • LintCode 31. partitionArray 数组划分
  • MySQL的数据类型
  • springMvc学习笔记(2)
  • SQLServer之创建数据库快照
  • TypeScript迭代器
  • 分享一份非常强势的Android面试题
  • 复杂数据处理
  • 给Prometheus造假数据的方法
  • 力扣(LeetCode)21
  • 微信端页面使用-webkit-box和绝对定位时,元素上移的问题
  • 微信支付JSAPI,实测!终极方案
  • 一份游戏开发学习路线
  • linux 淘宝开源监控工具tsar
  • 资深实践篇 | 基于Kubernetes 1.61的Kubernetes Scheduler 调度详解 ...
  • ​ubuntu下安装kvm虚拟机
  • ###项目技术发展史
  • #职场发展#其他
  • (145)光线追踪距离场柔和阴影
  • (175)FPGA门控时钟技术
  • (C语言)逆序输出字符串
  • (delphi11最新学习资料) Object Pascal 学习笔记---第8章第5节(封闭类和Final方法)
  • (简单) HDU 2612 Find a way,BFS。
  • (简单有案例)前端实现主题切换、动态换肤的两种简单方式
  • (理论篇)httpmoudle和httphandler一览
  • (三)elasticsearch 源码之启动流程分析
  • (转)iOS字体
  • (转)关于pipe()的详细解析
  • .mysql secret在哪_MYSQL基本操作(上)
  • .net 4.0发布后不能正常显示图片问题
  • .NET C# 使用 SetWindowsHookEx 监听鼠标或键盘消息以及此方法的坑
  • .net core 源码_ASP.NET Core之Identity源码学习
  • .NET Core 中插件式开发实现
  • .NET Framework .NET Core与 .NET 的区别
  • .NET 跨平台图形库 SkiaSharp 基础应用