详解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 相关文章推荐
jQuery中的each()详细介绍(推荐)
May 25 Javascript
JS不用正则验证输入的字符串是否为空(包含空格)的实现代码
Jun 14 Javascript
jquery动态添加文本并获取值的方法
Oct 12 Javascript
bootstrap读书笔记之CSS组件(上)
Oct 17 Javascript
bootstrap输入框组使用方法
Feb 07 Javascript
Bootstrap Tooltip显示换行和左对齐的解决方案
Oct 11 Javascript
vue实现提示保存后退出的方法
Mar 15 Javascript
vue中使用echarts制作圆环图的实例代码
Jul 27 Javascript
JavaScript动态创建二维数组的方法示例
Feb 01 Javascript
你了解vue3.0响应式数据怎么实现吗
Jun 07 Javascript
使用js实现一个简单的滚动条过程解析
Sep 10 Javascript
原生JavaScript之es6中Class的用法分析
Feb 23 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 文件上传后端处理实用技巧方法
2017/01/06 PHP
PHP实现执行外部程序的方法详解
2017/08/17 PHP
基于CI(CodeIgniter)框架实现购物车功能的方法
2018/04/09 PHP
Thinkphp 框架基础之入口文件功能、定义与用法分析
2020/04/27 PHP
打造基于jQuery的高性能TreeView(asp.net)
2011/02/23 Javascript
Java中Timer的用法详解
2015/10/21 Javascript
js行号显示的文本框实现效果(兼容多种浏览器 )
2015/10/23 Javascript
利用js+css+html实现固定table的列头不动
2016/12/08 Javascript
利用VUE框架,实现列表分页功能示例代码
2017/01/12 Javascript
分享19个JavaScript 有用的简写写法
2017/07/07 Javascript
JavaScript 通过Ajax 动态加载CheckBox复选框
2017/08/31 Javascript
实现div滚动条默认最底部以及默认最右边的示例代码
2017/11/15 Javascript
从零开始最小实现react服务器渲染详解
2018/01/26 Javascript
VUE Error: getaddrinfo ENOTFOUND localhost
2018/05/03 Javascript
JavaScript使用表单元素验证表单的示例代码
2019/08/20 Javascript
如何在Vue项目中添加接口监听遮罩
2021/01/25 Vue.js
浅谈Python peewee 使用经验
2017/10/20 Python
浅谈Scrapy框架普通反爬虫机制的应对策略
2017/12/28 Python
python如何在循环引用中管理内存
2018/03/20 Python
python调用tcpdump抓包过滤的方法
2018/07/18 Python
Django 登陆验证码和中间件的实现
2018/08/17 Python
python+opencv 读取文件夹下的所有图像并批量保存ROI的方法
2019/01/10 Python
Python应用领域和就业形势分析总结
2019/05/14 Python
Python3之字节串bytes与字节数组bytearray的使用详解
2019/08/27 Python
python 利用turtle模块画出没有角的方格
2019/11/23 Python
浅谈HTML5新增及移除的元素
2016/06/27 HTML / CSS
红色连衣裙精品店:Red Dress Boutique
2018/08/11 全球购物
美国家庭鞋店:Shoe Sensation
2019/09/27 全球购物
个人自我鉴定怎么写
2013/10/28 职场文书
经理管理专业自荐信范文
2013/12/31 职场文书
特色冷饮店创业计划书
2014/01/28 职场文书
社区中秋节活动方案
2014/01/29 职场文书
《再别康桥》教学反思
2014/02/12 职场文书
小学班级口号
2014/06/09 职场文书
浅析Python中的随机采样和概率分布
2021/12/06 Python
一文弄懂MySQL中redo log与binlog的区别
2022/02/15 MySQL