详解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代码压缩器
Oct 12 Javascript
使用jQuery操作Cookies的实现代码
Oct 09 Javascript
jQuery 瀑布流 绝对定位布局(二)(延迟AJAX加载图片)
May 23 Javascript
如何在JavaScript中实现私有属性的写类方式(二)
Dec 04 Javascript
js获取json元素数量的方法
Jan 27 Javascript
移动端jQuery修正Web页面滑动时div问题的两则实例
May 30 Javascript
jQuery实现的可编辑表格完整实例
Jun 20 Javascript
浅谈JS封闭函数、闭包、内置对象
Jul 18 Javascript
使用D3.js制作图表详解
Aug 13 Javascript
jQuery.validate.js表单验证插件的使用代码详解
Oct 22 jQuery
微信小程序中插入激励视频广告并获取收益(实例代码)
Dec 06 Javascript
js代码编写无缝轮播图
Sep 13 Javascript
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
php中对2个数组相加的函数
2011/06/24 PHP
php模拟post行为代码总结(POST方式不是绝对安全)
2012/02/22 PHP
ThinkPHP框架实现定时执行任务的两种方法分析
2018/09/04 PHP
PHP7内核CGI与FastCGI详解
2019/04/14 PHP
jquery 表单取值常用代码
2009/12/22 Javascript
jQuery-ui引入后Vs2008的无智能提示问题解决方法
2014/02/10 Javascript
使用delegate方法为一个tr标签加一个链接
2014/06/27 Javascript
Javascript实现获取及设置光标位置的方法
2015/07/21 Javascript
可以浮动某个物体的jquery控件用法实例
2015/07/24 Javascript
JavaScript编程中的Promise使用大全
2015/07/28 Javascript
jQuery插件开发精品教程让你的jQuery提升一个台阶
2016/01/27 Javascript
Node.js开发者必须了解的4个JS要点
2016/02/21 Javascript
Javascript oop设计模式 面向对象编程简单实例介绍
2016/12/13 Javascript
AngularJS基于ui-route实现深层路由的方法【路由嵌套】
2016/12/14 Javascript
jQuery动态移除和添加背景图片的方法详解
2017/03/07 Javascript
jQuery Ajax 实现分页 kkpager插件实例代码
2017/08/10 jQuery
微信小程序实现倒计时60s获取验证码
2020/04/17 Javascript
JavaScript事件对象深入详解
2018/12/30 Javascript
vue下载二进制流图片操作
2020/10/26 Javascript
JavaScript中常用的3种弹出提示框(alert、confirm、prompt)
2020/11/10 Javascript
[02:23]2016国际邀请赛中国区预选赛wings晋级之路
2016/06/29 DOTA
关于pip的安装,更新,卸载模块以及使用方法(详解)
2017/05/19 Python
Python subprocess模块功能与常见用法实例详解
2018/06/28 Python
Python封装原理与实现方法详解
2018/08/28 Python
python 在屏幕上逐字显示一行字的实例
2018/12/24 Python
python设计tcp数据包协议类的例子
2019/07/23 Python
pandas将多个dataframe以多个sheet的形式保存到一个excel文件中
2019/10/10 Python
谈一谈数组拼接tf.concat()和np.concatenate()的区别
2020/02/07 Python
python 按钮点击关闭窗口的实现
2020/03/04 Python
Python中常见的数制转换有哪些
2020/05/27 Python
初中学校对照检查材料
2014/08/19 职场文书
党的群众路线教育实践活动个人对照检查材料范文
2014/09/25 职场文书
老员工辞职信范文
2015/05/12 职场文书
销售人员管理制度
2015/08/06 职场文书
护理心得体会范文
2016/01/22 职场文书
Nginx域名转发https访问的实现
2021/03/31 Servers