async与await写法详解
async 与 await 可以使异步代码写法更加简洁,是在es2017引⼊的新特性,在最新版的nodejs及Chrome中都已经⽀持。async 函数
const fetch = require('node-fetch');
// function getZhihuColumn(id) {
//    const url = `zhuanlan.zhihu/api/columns/${id}`;
//    fetch(url)
//        .then(response => response.json())
//        .then(column => {
//            console.log(`NAME: ${column.title}`);
//            console.log(`INTRO: ${column.intro}`);
//        });
// }
使⽤async改写,使函数更加简洁
async function getZhihuColumn(id) {
const url = `zhuanlan.zhihu/api/columns/${id}`;
const response = await fetch(url);
const column = await response.json();
console.log(`NAME: ${column.title}`);
console.log(`INTRO: ${column.intro}`);
}
getZhihuColumn('feweekly')
将async函数⽤在promisechain中
/
/ async function getZhihuColumn(id) {
//    const url = `zhuanlan.zhihu/api/columns/${id}`;
//    const response = await fetch(url);
//    const column = await response.json();
//    console.log(`NAME: ${column.title}`);
//    console.log(`INTRO: ${column.intro}`);
// }
// function getZhihuColumn(id: any): Promise<any>
async function getZhihuColumn(id) {
const url = `zhuanlan.zhihu/api/columns/${id}`;
const response = await fetch(url);
return await response.json();
}
// function getZhihuColumn(id: any): Promise<any>
getZhihuColumn('feweekly')
.then(column => {
console.log(`NAME: ${column.title}`);
console.log(`INTRO: ${column.intro}`);
})
把任意类型的函数转换为async 函数
async ⽤在箭头函数
// async function getZhihuColumn(id) {
/
/    const url = `zhuanlan.zhihu/api/columns/${id}`;
//    const response = await fetch(url);
//    return await response.json();
// }
// 箭头函数
const getZhihuColumn = async (id) => {
const url = `zhuanlan.zhihu/api/columns/${id}`;
const response = await fetch(url);
return await response.json();
}
// getZhihuColumn('feweekly')
/
/ .then(column => {
//    console.log(`NAME: ${column.title}`);
//    console.log(`INTRO: ${column.intro}`);
//})
在全局作⽤域下使⽤async关键字是⾮法的需要声明⼀个匿名的函数表达式(async () => {
const columns = await getZhihuColumn('feweekly');
console.log(`NAME: ${column.title}`);
console.log(`INTRO: ${column.intro}`);
})()
// 另⼀种⽤法,在类的函数中使⽤async
class APIClient {
async getColumn(id) {
const url = `zhuanlan.zhihu/api/columns/${id}`;
const response = await fetch(url);
return await response.json();
}
}
(async () => {
const client = new APIClient();
const column = Column('feweekly');
console.log(`NAME: ${column.title}`);
console.log(`INTRO: ${column.intro}`);
})()
处理async函数中的错误的⼏种⽅式
async function getZhihuColumn(id) {
const url = `zhuanlan.zhihu/api/columns/${id}`;
const response = await fetch(url);
if (response.status !== 200) {
console.log()
throw new Error(); // 1
}
return await response.json();
}
const showColumnInfo = async (id) => {
try {  //2
const column = await getZhihuColumn(id);
console.log(`NAME: ${column.title}`);
console.log(`INTRO: ${column.intro}`);
} catch (error) {
console.log("test error")
console.log(error);
}
}
// showColumnInfo('feweekly2');
getZhihuColumn('feweekly1')
.then(column => {
console.log(`NAME: ${column.title}`);
console.log(`INTRO: ${column.intro}`);
}).catch(err=> { // 3
console.log("err2:" + err);
});
正确处理多个await操作的并⾏串⾏
添加await 的语句相当于处于⼀个线程中⼏个await串⾏执⾏,没有标记await的 并⾏执⾏。
const showColumnInfo = async () => {
try {
console.time('showColumnInfo');
// const column = await getZhihuColumn('feweekly');
// const toolingtips = await getZhihuColumn('toolingtips');
// 串⾏操作改为并⾏
const column2 = getZhihuColumn('feweekly');
const toolingtips2 = getZhihuColumn('toolingtips');
const column = await column2;
const toolingtips = await toolingtips2;
console.log(`NAME: ${column.title}`);
console.log(`INTRO: ${column.intro}`);
console.log(`NAME: ${toolingtips.title}`);
console.log(`INTRO: ${toolingtips.intro}`);
console.timeEnd('showColumnInfo');
} catch (error) {
console.log("test error")
console.log(error);
}
}
showColumnInfo();
使⽤Promise.all()让多个await操作并⾏
const [column, toolingtips] = await Promise.all([
getZhihuColumn('feweekly'),
getZhihuColumn('toolingtips')
])
console.log(`NAME: ${column.title}`);
console.log(`INTRO: ${column.intro}`);
console.log(`NAME: ${toolingtips.title}`);
console.log(`INTRO: ${toolingtips.intro}`);
console.timeEnd('showColumnInfo');
} catch (error) {
console.log("test error")
console.log(error);
}
}
showColumnInfo();
结合await和任意兼容then的代码
const bluebird = require('bluebird');
async function main() {
// await 有个隐式的调⽤ solve()
// const number = await 8088
// // const number = solve(8088)
// console.log(number);
// await 可以和任何兼容promise的函数接⼝或者说带有then接⼝结合在⼀起使⽤    console.log('');
await bluebird.delay(2000);// 延时
console.log('done!');
}
main();
在for循环中使⽤await
// const names = ['feweekly', 'toolingtips']
// // 属于循环中的串⾏
// for (const name of names) {
//    const column = await getZhihuColumn(name)
await和async使用方法//    console.log(`Name: ${name}`);
// }
const names = ['feweekly', 'toolingtips']
/
/ 这⾥已经将函数调⽤执⾏,直接返回结果
const promises = names.map(name => getZhihuColumn(name))        // 属于循环中的并⾏,将函数结果做同步,函数调⽤过程做异步        for (const promise of promises) {
const column = await promise
console.log(`Name: ${column.title}`);
}
console.timeEnd('showColumnInfo');
} catch (error) {
console.log("test error")
console.log(error);
}
}
showColumnInfo2();