JS:async与await的异步处理

news/2024/7/19 13:36:14 标签: js, es6/es7

简介

近来发现同事大佬写的代码中有await,觉得很好奇,所以抽空看了几篇文章,记录一下所学。

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

具体实现

对比一下await与async本身就是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);
  })
}

// promise
asyncFn().then((res) => {
  console.log(res);
}, (err) => {
  console.log(err);
})

// await
try {
  var res = await asyncFn();
  console.log(res);
} catch(err) {
  console.log(err);
}

// 如果有第二次请求的话,promise需要在then方法继续调用,再用then接受,过多的嵌套依然会增加阅读难度。而await async只需要像写同步代码一样继续书写就可以,它是解决异步编程回调地狱的终极手段。

举例

1.案例一

// 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’

2.案例二
如果你对结果有疑问,可以将var value1 = await asyncFn();中的await去掉,再在浏览器控制台执行一次。在这里插入图片描述
这两次对比一下,会发现第二次的resolve console是最后打印出来的,而第一次的是第一个打印的。

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

3.案例三
根据前两例可想而知,如果两个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会阻塞代码的执行,那么如何解决阻塞代码这个弊端呢?
方法:解决这个弊端的手段就是async声明。

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

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

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

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

最后

觉得有用的朋友请用你的金手指点一下赞,或者评论留言一起探讨技术!

参考文献:https://www.cnblogs.com/jsgoshu/p/11444404.html.


http://www.niftyadmin.cn/n/1867258.html

相关文章

JS:理解 JavaScript 中的执行上下文和执行栈

什么是执行上下文? 简而言之,执行上下文是评估和执行 JavaScript 代码的环境的抽象概念。每当 Javascript 代码在运行的时候,它都是在执行上下文中运行。 执行上下文的类型 JavaScript 中有三种执行上下文类型。 全局执行上下文 —— 这是…

JS:词法作用域和动态作用域

作用域 作用域是指程序源代码中定义变量的区域。 作用域规定了如何查找变量,也就是确定当前执行代码对变量的访问权限。 JavaScript 采用词法作用域(lexical scoping),也就是静态作用域。 静态作用域与动态作用域 因为 JavaScript 采用的是词法作用…

170615 windows 下 tensorflow1.2.0rc2 模型的保存与恢复

1. save and restore 英文教程,极力推荐 2. save and restore 中文教程,翻译地道 3. save and restore 简书教程,老版可用 4. save and restore youtube教程,视频操作 5. save and restore youtube代码),下载运行 …

VUE:JS中进行数组对象赋值,页面不能实时回显

简介 VUE项目中,有时候进行 数组对象 赋值时,不能实时回显到页面中,但是打印又有新的数据在里面。 具体实现 场景一:对象赋值新的属性时,页面不能回显。 原因:该对象本身是没有这个属性的。 解决方案&a…

H5:如何将vant-uploader上传的base64图片转换为文件上传到服务器

简介 H5中使用vant的uploader组件选择的图片,一次选择一张返回的是对象,一次选择多张返回的数组(包含一个个对象),但是这些对象都是base64的格式,不是想要的文件格式,于是需要我们转换。 具体…

VUE:v-for循环出来的el-form,js如何进行总的表单验证

简介 页面上,会有循环多个表单并验证的需求。如下图。左侧一个菜单,一个菜单下有多个规则,一个规则一个表单(之所以没有全部用一个表单的原因是要在切换规则时,保留之前所有的验证红色提示)。 具体实现 …

170615 创建tensorflow自己的nextbacth

stackover问题描述 nextbatch中文方法 代码来源:https://stackoverflow.com/questions/40994583/how-to-implement-tensorflows-next-batch-for-own-data 代码整理: # -*- coding: utf-8 -*- """ Created on Thu Jun 15 14:49:43 2…

VUE:快速实现一个省市区的级联选择器

简介 项目中,大概率会有选择地址的需求,但是在没有组件可用的情况下,就需要自己实现一个,接下来就以VUE项目为基础进行实操。 具体实现 第一步:准备一个全国地址的json文件(上级包含下级的从属关系数据&…