详解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 相关文章推荐
javascript 常用代码技巧大收集
Feb 25 Javascript
jQuery 常见操作实现方式和常用函数方法总结
May 06 Javascript
解决jquery的datepicker的本地化以及Today问题
May 23 Javascript
Jquery获取和修改img的src值的方法
Feb 17 Javascript
javascript中call,apply,bind的用法对比分析
Feb 12 Javascript
jQuery横向擦除焦点图特效代码分享
Sep 06 Javascript
基于jQuery插件实现点击小图显示大图效果
May 11 Javascript
jquery获取复选框的值的简单实例
May 26 Javascript
BootStrap iCheck插件全选与获取value值的解决方法
Aug 24 Javascript
详解vue.js下引入百度地图jsApi的两种方法
Jul 27 Javascript
关于angular引入ng-zorro的问题浅析
Sep 09 Javascript
vue使用watch监听属性变化
Apr 30 Vue.js
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
IIS6.0 开启Gzip方法及PHP Gzip函数分享
2014/06/08 PHP
Yii中CGridView关联表搜索排序方法实例详解
2014/12/03 PHP
PHP+JS实现大规模数据提交的方法
2015/07/02 PHP
详细解读PHP的Yii框架中登陆功能的实现
2015/08/21 PHP
解决Laravel 不能创建 migration 的问题
2019/10/09 PHP
jquery下checked取值问题的解决方法
2012/08/09 Javascript
ExtJs设置GridPanel表格文本垂直居中示例
2013/07/15 Javascript
JS实现拖动示例代码
2013/11/01 Javascript
Jquery实现纵向横向菜单
2016/01/24 Javascript
微信小程序 网络API Websocket详解
2016/11/09 Javascript
javascript构造函数以及原型对象的理解
2017/01/13 Javascript
Webpack执行命令参数详解
2017/06/17 Javascript
分享vue.js devtools遇到一系列问题
2017/10/24 Javascript
11行JS代码制作二维码生成功能
2018/03/09 Javascript
js实现ATM机存取款功能
2020/10/27 Javascript
Vue注册组件命名时不能用大写的原因浅析
2019/04/25 Javascript
修改vue源码实现动态路由缓存的方法
2020/01/21 Javascript
原生微信小程序开发中 redux 的使用详解
2021/02/18 Javascript
python时间整形转标准格式的示例分享
2014/02/14 Python
Python with用法实例
2015/04/14 Python
python基于socket实现网络广播的方法
2015/04/29 Python
Python中有趣在__call__函数
2015/06/21 Python
CentOS 7下安装Python 3.5并与Python2.7兼容并存详解
2017/07/07 Python
利用python编写一个图片主色转换的脚本
2017/12/07 Python
使用pandas读取csv文件的指定列方法
2018/04/21 Python
python在文本开头插入一行的实例
2018/05/02 Python
selenium使用chrome浏览器测试(附chromedriver与chrome的对应关系表)
2018/11/29 Python
树莓派4B安装Tensorflow的方法步骤
2020/07/16 Python
python根据用户需求输入想爬取的内容及页数爬取图片方法详解
2020/08/03 Python
翻译学院毕业生自荐书
2014/02/02 职场文书
思想品德自我评价
2014/02/04 职场文书
餐饮营销方案
2014/02/23 职场文书
群众路线个人整改方案
2014/10/25 职场文书
简历中的自我评价应该这样写!
2019/07/12 职场文书
JS如何使用剪贴板操作Clipboard API
2021/05/17 Javascript
Python实现数据的序列化操作详解
2022/07/07 Python