博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
深入理解await与async
阅读量:4843 次
发布时间:2019-06-11

本文共 2901 字,大约阅读时间需要 9 分钟。

1-1.await

  • await的意思就是等待。它后面可以跟一个表达式。如果是值(如字符串、数字、普通对象等等)的话,返回值就是本身的值。
  • 不过最常用的是后面跟一个promise对象。await会等待这个promise的状态由pending转为fulfilled或者rejected。在此期间它会阻塞,延迟执行await语句后面的语句。
  • 如果promise对象的结果是resolve,它会将resolve的值,作为await表达式的运算结果。
语法糖本质

​ 其实awaitasync本身就是promise化编程的一种语法糖。对比一下两种写法。

// 异步promise化的函数--模拟请求后端接口function asyncFn () {  return new Promise(function (resolve, reject) {    setTimeout(function () {      if (true) {        console.log('resolve console')        resolve('resolve return')      } else {        reject('reject return')      }    }, 2000)  })}// promiseasyncFn().then((res) => {  console.log(res)}, (err) => {  console.log(err)})// awaittry {  var res = await asyncFn()  console.log(res)} catch(err) {  console.log(err)}// 如果有第二次请求的话,promise需要在then方法继续调用,再用then接受,过多的嵌套依然会增加阅读难度。而await async只需要像写同步代码一样继续书写就可以,它是解决异步编程回调地狱的终极手段。
例一
// ps:由于js本身现在已经限制了await必须用在async函数中,否则会报错。所以请将下面的复制粘贴到浏览器控制台查看结果function asyncFn () {  return new Promise(function (resolve, reject) {    setTimeout(function () {      if (true) {        console.log('resolve console')        resolve('resolve return')      } else {        reject('reject return')      }    }, 2000)  })}var value1 = await asyncFn()var value2 = await 'plain text'console.log(value1)console.log(value2)//浏览器会依次打印 ‘resolve console’ ‘resolve return’ ‘plain text’
例二

如果你对结果有疑问,可以将asyncFn前面的await去掉,再在浏览器控制台执行一次。

006y8mN6ly1g6kfywwi9aj30t40i40vh.jpg

这两次对比一下,会发现第二次的resolve console是最后打印出来的,而第一次的是第一个打印的。

根本原因就是第一次代码中await阻塞了后面语句的执行,等待promise确定结果后继续执行后面语句。

例三

根据前两例可想而知,如果两个await的后面跟着的都是promise对象。那么第二个await等待的时间是它本身等待的时间加上第一个await等待的时间

function asyncFn1 () {  return new Promise(function (resolve, reject) {    setTimeout(function () {      if (true) {        console.log('resolve console1')        resolve('resolve return1')      } else {        reject('reject return1')      }    }, 2000)  })}function asyncFn2 () {  return new Promise(function (resolve, reject) {    setTimeout(function () {      if (true) {        console.log('resolve console2')        resolve('resolve return2')      } else {        reject('reject return2')      }    }, 2000)  })}var value1 = await asyncFn1()var value2 = await asyncFn2()// 复制并执行,会发现2s后打印了‘resolve console1’,4s后打印了‘resolve console2’
思考
// 已经知道了await会阻塞代码的执行,如果我们在实际开发中有这样的代码。function fn () {  // 假设request是请求后端接口  var value = await request()  console.log(value)  // ...}fn()var arr = []arr.push('1')// ...其他不依赖后端接口逻辑

​ 在fn调用后,由于await的阻塞,必然会影响到下面的逻辑。在实际开发中,如果后端接口5s才响应,那么下面的代码就需要等待5s。显然这是不合理的,为了解决这种现象,就需要async声明。

1-2.async

​ 之前我们知道了await会阻塞代码的执行。而解决这个弊端的手段就是async声明。

async function asyncFn () {  return 'async'}console.log(asyncFn())

​ 控制台打印一下,会发现打印的是一个promise对象。而且是Promise.resolve对象。resolve的值就是asyncFn的函数返回值async

006y8mN6ly1g6kh5ejq2mj30lw07ijsn.jpg

​ 如果函数没有返回值的话,它自然返回的会是Promise.resolve(undefined)

其实之所以async声明能解决await的阻塞问题,就是因为async声明将函数作了一层promise包装,这样内部的异步操作其实就是由pending转为resolve或者reject的过程。这样函数本身就能够随意调用,函数内部的await也不会再影响到函数外部的代码执行。

转载于:https://www.cnblogs.com/jsgoshu/p/11444404.html

你可能感兴趣的文章
Redis 持久化
查看>>
大龄屌丝自学笔记--Java零基础到菜鸟--019
查看>>
转:黑客讲故事:攻下隔壁女生路由器后,我都做了些什么
查看>>
hdu 5463 Clarke and minecraft(贪心)
查看>>
Css轮廓
查看>>
Perl入门笔记2之第二章 标量数据
查看>>
HTTPS科普(转)
查看>>
Flask上下文
查看>>
微信接入详细流程 分享给好友和朋友圈
查看>>
快速使用 Thinkphp 之二: 创建自己的应用项目
查看>>
怎样存钱利息最大及怎样买房付款最省钱问题
查看>>
多机共享开发证书
查看>>
【线段树】POJ 3667 Hotel 区间合并
查看>>
MongoDB ObjectId
查看>>
Tsung CentOS 操作系统下搭建tsung性能测试环境_Part 2
查看>>
Docker实战(五)之端口映射与容器互联
查看>>
记一次js之button问题
查看>>
初学python类
查看>>
springmvc学习笔记(18)-json数据交互
查看>>
STL容器介绍
查看>>