Async
函数作为异步解决方案的最优解,async/await
特性能让我们编写出相比回调地狱和Promise
链式调用更直观、更容易理解的代码,Async
函数返回一个Promise
对象,可以使用then()
方法添加回调函数,当函数执行的时候,一旦遇到await
就会先返回,等到异步操作完成,再接着执行函数体内后面的语句
01 初识 async/await
代码语言:javascript复制const fetch = require('node-fetch');
async function JianShuRequest(id) {
const url = `https://www.jianshu.com/users/b0c7095032f3/collections_and_notebooks?slug=${id}`,
request = await fetch(url),
data = await request.json();
console.log(`bookname: ${data.notebooks[4].name}`);
}
JianShuRequest('b0c7095032f3')
02 将 Async 函数用在 Promise 链中
代码语言:javascript复制const fetch = require('node-fetch');
async function JianShuRequest(id) {
const url = `https://www.jianshu.com/users/b0c7095032f3/collections_and_notebooks?slug=${id}`,
request = await fetch(url);
return await request.json();
}
JianShuRequest('b0c7095032f3').then(data => {
console.log(`bookname: ${data.notebooks[4].name}`);
})
03 使用 await 进行调用
代码语言:javascript复制const fetch = require('node-fetch');
async function JianShuRequest(id) {
const url = `https://www.jianshu.com/users/b0c7095032f3/collections_and_notebooks?slug=${id}`,
request = await fetch(url);
return await request.json();
}
(async () => {
const data = await JianShuRequest('b0c7095032f3');
console.log(`bookname: ${data.notebooks[4].name}`);
})()
代码语言:javascript复制const fetch = require('node-fetch');
async function JianShuRequest(id) {
const url = `https://www.jianshu.com/users/b0c7095032f3/collections_and_notebooks?slug=${id}`,
request = await fetch(url);
return await request.json();
}
var bookname = async () => {
const data = await JianShuRequest('b0c7095032f3');
console.log(`bookname: ${data.notebooks[4].name}`);
}
bookname()
04 await 并行
通过移动await
关键词的位置实现多个await
操作串行或者并行
const fetch = require('node-fetch');
async function JianShuRequest(id) {
const url = `https://www.jianshu.com/users/b0c7095032f3/collections_and_notebooks?slug=${id}`,
request = await fetch(url);
return await request.json();
}
var bookname = async () => {
console.time('time');
const data_1 = await JianShuRequest('b0c7095032f3');
const data_2 = await JianShuRequest('b0c7095032f3');
console.log(`bookname: ${data_1.notebooks[2].name}`);
console.log(`bookname: ${data_2.notebooks[4].name}`);
console.timeEnd('time');
}
bookname()
代码语言:javascript复制const fetch = require('node-fetch');
async function JianShuRequest(id) {
const url = `https://www.jianshu.com/users/b0c7095032f3/collections_and_notebooks?slug=${id}`,
request = await fetch(url);
return await request.json();
}
var bookname = async () => {
console.time('time');
const dataPromise_1 = JianShuRequest('b0c7095032f3');
const dataPromise_2 = JianShuRequest('b0c7095032f3');
const data_1 = await dataPromise_1;
const data_2 = await dataPromise_2;
console.log(`bookname: ${data_1.notebooks[2].name}`);
console.log(`bookname: ${data_2.notebooks[4].name}`);
console.timeEnd('time');
}
bookname()
根据两种方式得到的数据对比,并行所运行的时间更短,其主要思路是,先触发所有的请求,得到Promise
对象,再通过await
等待resolve
返回的结果
05 使用 try catch 捕捉错误
代码语言:javascript复制const fetch = require('node-fetch');
async function JianShuRequest(id) {
const url = `https://www.jianshu.com/users/b0c7095032f3/collections_and_notebooks?slug=${id}`,
request = await fetch(url);
if(request.status != 200) {
throw new Error(request.statusText);
}
return await request.json();
}
const showJianShuRequest = async (id) => {
try {
const data = await JianShuRequest(id);
console.log(`bookname: ${data.notebooks[4].name}`);
}catch (err) {
console.error(err);
}
}
showJianShuRequest('666666');
06 使用 Promise.all() 实现多个异步操作的并行
代码语言:javascript复制const fetch = require('node-fetch');
async function JianShuRequest(id) {
const url = `https://www.jianshu.com/users/b0c7095032f3/collections_and_notebooks?slug=${id}`,
request = await fetch(url);
return await request.json();
}
const showJianShuRequest = async () => {
const [data_1, data_2] = await Promise.all([
JianShuRequest('b0c7095032f3'),
JianShuRequest('b0c7095032f3'),
])
console.log(`bookname_1: ${data_1.notebooks[2].name}`);
console.log(`bookname_2: ${data_2.notebooks[4].name}`);
}
showJianShuRequest();
07 在循环中正确使用 await
代码语言:javascript复制const fetch = require('node-fetch'),
bluebird = require('bluebird');
async function JianShuRequest(id) {
await bluebird.delay(1000);
const url = `https://www.jianshu.com/users/b0c7095032f3/collections_and_notebooks?slug=${id}`,
request = await fetch(url);
return await request.json();
}
const showJianShuRequest = async () => {
console.time('time');
const names = ['b0c7095032f3', 'b0c7095032f3'];
for(const name of names){
const data = await JianShuRequest(name);
console.log(`bookname_1: ${data.notebooks[2].name}`);
console.log(`bookname_2: ${data.notebooks[4].name}`);
}
console.timeEnd('time');
}
showJianShuRequest();
代码语言:javascript复制const fetch = require('node-fetch'),
bluebird = require('bluebird');
async function JianShuRequest(id) {
await bluebird.delay(1000);
const url = `https://www.jianshu.com/users/b0c7095032f3/collections_and_notebooks?slug=${id}`,
request = await fetch(url);
return await request.json();
}
const showJianShuRequest = async () => {
console.time('time');
const names = ['b0c7095032f3', 'b0c7095032f3'];
const promises = names.map(x => JianShuRequest(x))
for (const promise of promises) {
const data = await promise;
console.log(`bookname_1: ${data.notebooks[2].name}`);
console.log(`bookname_2: ${data.notebooks[4].name}`);
}
console.timeEnd('time');
}
showJianShuRequest();
参考资料 ECMAScript 6 入门——async 函数 玩转异步 JS :async/await 简明教程 三分钟学会用ES7中的Async/Await进行异步编程
本篇的内容到这里就全部结束了,源码我已经发到了GitHub async-await 上了,有需要的同学可自行下载