理解ES7中的async/await

优势是:就是解决多层异步回调的嵌套

 从字面上理解 async/await, async是 "异步"的含义,await可以认为是 async wait的简写,因此可以理解 async 用于声明一个function是异步的,而await用于等待一个异步方法执行完成返回的值(返回值可以是一个Promise对象或普通返回的值)。
注意:await 只能出现在 async函数中。

1-1 async的作用?
首先来理解async函数是怎么处理返回值的,我们以前写代码都是通过return语句返回我们想要的值,但是async与return有什么区别呢? 下面我们看如下代码:

async function testAsync() {
return 'hello world';
}
const result = testAsync();
console.log(result); // 打印出来看到 返回一个promise对象

如上代码,我们输出的是一个Promise对象。因此 async返回的是一个Promise对象,因此我们可以使用 then()链来处理这个Promise对象。像如下代码:

async function testAsync() {
return 'hello world';
}
const result = testAsync();
result.then(v => {
console.log(v); // 输出 hello world
});

但是如果 async函数没有返回值的话,那么就会返回 undefined; 如下代码:

async function testAsync() {
return;
}
const result = testAsync();
result.then(v => {
console.log(v); // 输出 undefined
});

1-2 await的作用?
从语义上说,await是在等待一个async函数完成的,async函数返回的是一个Promise对象,await等待的是一个表达式,这个表达式的计算结果是Promise对象或其他值。
async函数返回一个Promise对象,await作用是用于等待一个async函数的返回值。
await函数后面可以接普通函数调用或直接量,请看如下代码:

function getSomething() {
return 'something';
} async function testAsync() {
return Promise.resolve('hello');
} async function test () {
const v1 = await getSomething();
const v2 = await testAsync();
console.log(v1); // something
console.log(v2); // hello
}
test();

注意:await 是等待async函数返回的Promise对象或其他值,await是一个运算符,用于组成表达式, 如果等待的是一个Promise对象,await会阻塞后面的代码(async调用不会造成堵塞,它内部所有的堵塞
都被封装在一个Promise对象中异步执行),等待Promise对象的resolve,然后得到resolve的值,作为await表达式的运输结果。

1-3 async/await 的一起使用的作用及优势在哪?
我们先不用 async/await, 来看看使用setTimeout模拟异步操作如下代码:

var test = function(time) {
return new Promise((resolve, reject) => {
setTimeout(function(){
resolve('hello world');
}, time)
});
}; test(1000).then((v) => {
console.log(v);
});

如果改用 async/await 代码如下:

var testAsync = function(time) {
return new Promise((resolve, reject) => {
setTimeout(function(){
resolve('hello world');
}, time)
});
}; async function test(time) {
const v = await testAsync(time);
console.log(v); // hello world
}
test(1000);

看上面的代码,反而会觉得 使用 async/await 代码变得多一点,复杂一点,但是结果貌似都一样,那么使用 async/await的优势在哪?

1-4 async/await的优势在于处理then链

单一的Promise链貌似不能发现 async/await的优势,但是如果需要处理多个Promise组成的then链的时候,优势可以看出来,因为Promise是通过then链来解决多层回调的问题,现在我们又可以使用
async/await来进一步优化,他们的优点就是解决多层异步回调的嵌套。

假设我们现在有一个需求是,分多个步骤完成,每个步骤都是异步的,并且后面的异步都需要依赖于上一个异步回调返回的数据,进行往下传递。我们先用 setTimeout来模拟异步操作。

function useTimeout (t) {
return new Promise((resolve, reject) => {
setTimeout(()=> {
resolve(t+100)
}, t);
});
} function step1(t) {
console.log(`step1 with ${t}`); // step1 with 300
return useTimeout(t);
} function step2(t) {
console.log(`step2 with ${t}`); // step2 with 400
return useTimeout(t);
} function step3(t) {
console.log(`step3 with ${t}`); // step3 with 500
return useTimeout(t);
} function test() {
const time1 = 300;
step1(time1)
.then(time2 => step2(time2))
.then(time3 => step3(time3))
.then(res => {
console.log(`result is ${res}`); // result is 600
})
}
test();

如果我们使用 async/await来实现,代码变为如下:

function useTimeout (t) {
return new Promise((resolve, reject) => {
setTimeout(()=> {
resolve(t+100)
}, t);
});
} function step1(t) {
console.log(`step1 with ${t}`); // step1 with 300
return useTimeout(t);
} function step2(t) {
console.log(`step2 with ${t}`); // step2 with 400
return useTimeout(t);
} function step3(t) {
console.log(`step3 with ${t}`); // step3 with 500
return useTimeout(t);
} async function test() {
const time1 = 300;
const time2 = await step1(time1);
const time3 = await step2(time2);
const result = await step3(time3);
console.log(`result is ${result}`);
}
test();

上面我们可以看到 使用async/await 代码看起来都是同步的,等第一步完成后,再执行第二步,依次类推..... 并且不需要更多的回调函数嵌套。

下面我们再来看下我们之前讲的,后面的步骤需要上一个步骤的结果传递进去,使用async/await的优势可能更明显。
如下代码:

function useTimeout (t) {
return new Promise((resolve, reject) => {
setTimeout(()=> {
resolve(t+100)
}, t);
});
} function step1(t1) {
console.log(`step1 with ${t1}`); // step1 with 300
return useTimeout(t1);
} function step2(t1, t2) {
console.log(`step2 with ${t1} and ${t2}`); // step2 with 300 and 400
return useTimeout(t1+t2);
} function step3(t1, t2, t3) {
console.log(`step3 with ${t1} and ${t2} and ${t3}`); // step3 with 300 and 400 and 800
return useTimeout(t1+t2+t3);
} async function test() {
const time1 = 300;
const time2 = await step1(time1);
const time3 = await step2(time1, time2);
const result = await step3(time1, time2, time3);
console.log(`result is ${result}`); // result is 1600
}
test();

1-5 捕捉错误
我们可以使用 try catch 来捕获错误,如下代码:

var sleep = function (time) {
return new Promise((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
}
}; start();

理解ES7中的async/await的更多相关文章

  1. 理解C#中的 async await

    前言 一个老掉牙的话题,园子里的相关优秀文章已经有很多了,我写这篇文章完全是想以自己的思维方式来谈一谈自己的理解.(PS:文中涉及到了大量反编译源码,需要静下心来细细品味) 从简单开始 为了更容易理解 ...

  2. JavaScript ES7 中使用 async/await 解决回调函数嵌套问题

    原文链接:http://aisk.me/using-async-await-to-avoid-callback-hell/ JavaScript 中最蛋疼的事情莫过于回调函数嵌套问题.以往在浏览器中, ...

  3. 关于ES7中的async/await在客户端和服务端上的实践

    一.前言 在项目中经常遇到处理异步请求的情况,面对层层的嵌套,回调显示那么苍白无力: async / await是ES7的重要特性之一,也是目前社区里公认的优秀异步解决方案,既然这样就用上吧. 二.配 ...

  4. ES7中的async和await

    ES7中的async和await 在上一章中,使用Promise将原本的回调方式转换为链式操作,这就将一个个异步执行的操作串在一条同步线上了.下一次的操作必须等待当前操作的结束. 使用Promise的 ...

  5. 【TypeScript】如何在TypeScript中使用async/await,让你的代码更像C#。

    [TypeScript]如何在TypeScript中使用async/await,让你的代码更像C#. async/await 提到这个东西,大家应该都很熟悉.最出名的可能就是C#中的,但也有其它语言也 ...

  6. 在现有代码中通过async/await实现并行

    在现有代码中通过async/await实现并行 一项新技术或者一个新特性,只有你用它解决实际问题后,才能真正体会到它的魅力,真正理解它.也期待大家能够多分享解一些解决实际问题的内容. 在我们遭遇“黑色 ...

  7. js中的async await

    JavaScript 中的 async/await 是属于比较新的知识,在ES7中被提案在列,然而我们强大的babel粑粑已经对它进行列支持! 如果开发中使用了babel转码,那么就放心大胆的用吧. ...

  8. [C#] .NET4.0中使用4.5中的 async/await 功能实现异

    好东西需要分享 原文出自:http://www.itnose.net/detail/6091186.html 在.NET Framework 4.5中添加了新的异步操作库,但是在.NET Framew ...

  9. 在Silverlight中使用async/await

    现在 async/await 大行其道,确实,有了 async/await ,异步编程真是简单多了,个人觉得 async/await 的出现,给开发者还来的方便,绝不亚于当年 linq 的出现. 但要 ...

随机推荐

  1. Java 雇员管理小练习(理解面向对象编程)

    在学习集合框架的时候,初学者很容易练习到学生管理系统.雇员管理体统等练习题.在学习集合框架之前,基本上Java基本语法都学完了,集合框架也从侧面的检验对前面学习的理解.下面用一个曾经做过的练习题,回顾 ...

  2. Nginx拦截指定国家的IP

    Nginx拦截指定国家的IP 一.下载GeoIP数据库 wget http://geolite.maxmind.com/download/geoip/api/c/GeoIP.tar.gz wget h ...

  3. 10折交叉验证(10-fold Cross Validation)与留一法(Leave-One-Out)、分层采样(Stratification)

    10折交叉验证 我们构建一个分类器,输入为运动员的身高.体重,输出为其从事的体育项目-体操.田径或篮球. 一旦构建了分类器,我们就可能有兴趣回答类似下述的问题: . 该分类器的精确率怎么样? . 该分 ...

  4. Docker 轻量级图形管理软件 Portainer

    安装 docker swarm :https://www.cnblogs.com/klvchen/p/9437758.html portainer 集群启动 docker volume create ...

  5. 【代码笔记】Web-ionic 网格(Grid)

    一,效果图. 二,代码. <!DOCTYPE html> <html> <head> <meta charset="utf-8"> ...

  6. Salesforce小知识:在简档中设置Visualforce页面的权限

    简档(Profile)中的 Visualforce 页面访问权限 在Salesforce中,对于自定义的简档,可以设置"Visualforce 页面访问"的权限. Visualfo ...

  7. Nginx入门到精通

    目录 入门篇 1.Nginx的介绍 2.Nginx的安装 3.Nginx的深入剖析 4.Nginx的虚拟主机 5.Nginx的常用功能 6.Nginx的日志剖析 7.Nginx的location剖析 ...

  8. javascript避免dom事件重复触发

    /** * 为指定控件添加限制性事件, 该事件在触发之后, 会被移除, 并在指定的时间间隔后, 重新绑定, 适用于避免控件事件被误操作重复触发的场景 * @param {String} domID 要 ...

  9. WindowsErrorCode

    0 操作成功完成.1 功能错误.2 系统找不到指定的文件.3 系统找不到指定的路径.4 系统无法打开文件.5 拒绝访问.6 句柄无效.7 存储控制块被损坏.8 存储空间不足, 无法处理此命令.9 存储 ...

  10. VMware导入OVF时报错(未能部署OVF包用户取消了任务的解决办法)

    阅读目录: 1.问题 2.原因 3.解决方案 问题:部署OVF模版的时候报错“用户取消了任务” 原因:导出ovf模板时,虚拟CD-ROM的选项要选[客户端设备],否则导入时报错“用户取消了任务” 解决 ...