详解node Async/Await 更好的异步编程解决方案


Posted in Javascript onMay 10, 2018

一、异步编程的终极解决方案

前几天写过关于 javascript 异步操作的文章《Javascript Promise 详解》. 最近在学习 Puppeteer 的时候又发现另一种异步编程解决方案:Async/Await.

异步操作是 JavaScript 编程的麻烦事,麻烦到一直有人提出各种各样的方案,试图解决这个问题。 从最早的回调函数,到 Promise 对象,再到 Generator 函数,每次都有所改进,但又让人觉得不彻底。 它们都有额外的复杂性,都需要理解抽象的底层运行机制。

在 Async 函数出来之后,有人认为它是异步编程的最终解决方案。因为有了 Async/Await 之后,你根本就不用关心是它是不是异步编程。

二、基本用法

async 函数返回一个 Promise 对象,可以使用 then 方法添加回调函数。 当函数执行的时候,一旦遇到 await 就会先返回,等到触发的异步操作完成,再接着执行函数体内后面的语句。

下面是一个栗子:

var sleep = function (time) {
  return new Promise(function (resolve, reject) {
    setTimeout(function () {
      resolve();
    }, time);
  })
};

var start = async function () {
  // 在这里使用起来就像同步代码那样直观
  console.log('start');
  await sleep(3000);
  console.log('end');
};

start();

执行上面的代码,你会发现,控制台先输出start,稍等3秒后,输出了end。

三、注意事项

1、await 命令只能用在 async 函数之中,如果用在普通函数,就会报错。

async function dbFuc(db) {
 let docs = [{}, {}, {}];

 // 报错
 docs.forEach(function (doc) {
  await db.post(doc);
 });
}

2、await 表示在这里等待promise返回结果了,再继续执行。

var sleep = function (time) {
  return new Promise(function (resolve, reject) {
    setTimeout(function () {
      // 返回 ‘ok'
      resolve('ok');
    }, time);
  })
};

var start = async function () {
  let result = await sleep(3000);
  console.log(result); // 收到 ‘ok'
};

3、await 后面跟着的应该是一个promise对象。

如果是同步执行的代码没有必要使用 await 修饰了。

4、await 只能使用在原生语法中,比如在 forEeach 结构中使用 await 是无法正常工作的,必须使用 for 循环的原生语法。

async function dbFuc(db) {
 let docs = [{}, {}, {}];

 // 可能得到错误结果
 docs.forEach(async function (doc) {
  await db.post(doc);
 });
}

如果确实希望多个请求并发执行,可以使用 Promise.all 方法。

async function dbFuc(db) {
 let docs = [{}, {}, {}];
 let promises = docs.map((doc) => db.post(doc));

 let results = await Promise.all(promises);
 console.log(results);
}

四、错误捕获

既然.then(..)不用写了,那么.catch(..)也不用写,可以直接用标准的try catch语法捕捉错误。

var sleep = function (time) {
  return new Promise(function (resolve, reject) {
    setTimeout(function () {
      // 模拟出错了,返回 ‘error'
      reject('error');
    }, time);
  })
};

var start = async function () {
  try {
    console.log('start');
    await sleep(3000); // 这里得到了一个返回错误
    
    // 所以以下代码不会被执行了
    console.log('end');
  } catch (err) {
    console.log(err); // 这里捕捉到错误 `error`
  }
};

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
js 方法实现返回多个数据的代码
Apr 30 Javascript
Javascript中浮点数相乘的一个解决方法
Jun 03 Javascript
node.js开发中使用Node Supervisor实现监测文件修改并自动重启应用
Nov 04 Javascript
jQuery实现点击小图显示大图代码分享
Aug 25 Javascript
js实现input密码框提示信息的方法(附html5实现方法)
Jan 14 Javascript
javascript 四十条常用技巧大全
Sep 09 Javascript
利用js编写响应式侧边栏
Sep 17 Javascript
Javascript获取图片原始宽度和高度的方法详解
Sep 20 Javascript
js中class的点击事件没有效果的解决方法
Oct 13 Javascript
easyui combogrid实现本地模糊搜索过滤多列
May 13 Javascript
移动端H5页面返回并刷新页面(BFcache)的方法
Nov 06 Javascript
详解JQuery基础动画操作
Apr 12 jQuery
Javascript Promise用法详解
May 10 #Javascript
jQuery实现模糊查询的方法分析
May 10 #jQuery
async/await地狱该如何避免详解
May 10 #Javascript
Angular4.x通过路由守卫进行路由重定向实现根据条件跳转到相应的页面(推荐)
May 10 #Javascript
JS中的JSON对象的定义和取值实现代码
May 09 #Javascript
js循环map 获取所有的key和value的实现代码(json)
May 09 #Javascript
js合并两个数组生成合并后的key:value数组
May 09 #Javascript
You might like
Content-type 的说明
2006/10/09 PHP
PHP中explode函数和split函数的区别小结
2016/08/24 PHP
ThinkPHP3.1.2 使用cli命令行模式运行的方法
2020/04/14 PHP
JS网页图片按比例自适应缩放实现方法
2014/01/15 Javascript
javascript获取文档坐标和视口坐标
2015/05/26 Javascript
一道关于JavaScript变量作用域的面试题
2016/03/08 Javascript
JavaScript数据绑定实现一个简单的 MVVM 库
2016/04/08 Javascript
在JavaScript中调用Java类和接口的方法
2016/09/07 Javascript
实现一个简单的vue无限加载指令方法
2017/01/10 Javascript
JavaScript实现左右下拉框动态增删示例
2017/03/09 Javascript
JavaScript设计模式之代理模式简单实例教程
2018/07/03 Javascript
小程序实现多列选择器
2019/02/15 Javascript
微信小程序实现的绘制table表格功能示例
2019/04/26 Javascript
基于javascript实现贪吃蛇经典小游戏
2020/04/10 Javascript
解决Vue router-link绑定事件不生效的问题
2020/07/22 Javascript
[47:52]完美世界DOTA2联赛PWL S2 PXG vs InkIce 第二场 11.26
2020/11/30 DOTA
[01:04:02]DOTA2-DPC中国联赛 正赛 Elephant vs IG BO3 第二场 1月24日
2021/03/11 DOTA
Python selenium 父子、兄弟、相邻节点定位方式详解
2016/09/15 Python
python 字符串转列表 list 出现\ufeff的解决方法
2017/06/22 Python
Python实现正弦信号的时域波形和频谱图示例【基于matplotlib】
2018/05/04 Python
Python装饰器语法糖
2019/01/02 Python
对python:threading.Thread类的使用方法详解
2019/01/31 Python
python 实现提取某个索引中某个时间段的数据方法
2019/02/01 Python
使用matlab 判断两个矩阵是否相等的实例
2020/05/11 Python
python调用百度AI接口实现人流量统计
2021/02/03 Python
世界最大的票务市场:viagogo
2017/02/16 全球购物
澳洲健康食品网上商店:Aussie Health Products
2018/06/15 全球购物
馥绿德雅美国官方网站:Rene Furterer头皮护理专家
2019/05/01 全球购物
美国围栏公司:Walpole Outdoors
2019/11/19 全球购物
鲜果饮品店创业计划书
2014/01/21 职场文书
教师自我剖析材料(群众路线)
2014/09/29 职场文书
关于开学的感想
2015/08/10 职场文书
子女赡养老人协议书
2016/03/23 职场文书
公开致歉信
2019/06/24 职场文书
MySQL官方导出工具mysqlpump的使用
2021/05/21 MySQL
AJAX引擎原理以及XmlHttpRequest对象的axios、fetch区别详解
2022/04/09 Javascript