js有不少异步处理的解决方案,而async/await
就是其中的一种,最近有在学习和运用koa,在服务端中,不多用到promise,而是选择了更加优雅的async/await
。固然,一种新方案的出现,咱们不光须要学会怎么写,也要学会他的原理。express
async/await
从字面意思上很好理解,async
是异步的意思,await
有等待的意思,而二者的用法上也是如此。async
用于申明一个function
是异步的,而await
用于等待一个异步方法执行完成。promise
async的语法很简单,就是在函数开头加一个关键字,示例以下:bash
async function f() {
return 1;
}
复制代码
async关键字的意思很简单,就是函数返回的是一个promise。koa
async function f() {
return 1;
}
f().then((res) => {
console.log(res)
}) // 1
复制代码
async函数会返回一个promise对象,若是function中返回的是一个值,async直接会用Promise.resolve()
包裹一下返回。异步
关键词await是等待的意思,那么他在等什么呢? 在MDN上写的是:async
[return_value] = await expression;
复制代码
等的是一个表达式,那么表达式,能够是一个常量,变量,promise,函数等。函数
function getSomething() {
return "something";
}
async function testAsync() {
return Promise.resolve("hello async");
}
async function test() {
const v1 = await getSomething();
const v2 = await testAsync();
console.log(v1, v2);
}
test(); // something hello async
复制代码
await操做符等的是一个返回的结果,那么若是是同步的状况,那就直接返回了。学习
那若是是异步的状况呢,异步的状况下,await会阻塞整一个流程,直到结果返回以后,才会继续下面的代码。ui
阻塞代码是一个很可怕的事情,而async函数,会被包在一个promise中,异步去执行。因此await只能在async函数中使用,若是在正常程序中使用,会形成整个程序阻塞,得不偿失。 spa
promise并非只有一种resolve,还有一种reject的状况。而await只会等待一个结果,那么发生错误了该怎么处理呢?
async function myFunction() {
try {
await Promise.reject('1');
} catch (err) {
console.log(err);
}
}
myFunction(); // 1
复制代码
async function myFunction() {
await Promise.reject('1').catch((err) => {
console.log(err);
});
}
myFunction(); // 1
复制代码
promise最大的问题就是在于业务复杂以后,then内部的逻辑也变得复杂,或者循环的异步嵌套场景等,会写出来不那么优美。
我随意列举一个嵌套的例子,而后分别用async/await
和promise
,你就能感觉到二者之间的差距:
function takeLongTime(n) {
return new Promise(resolve => {
setTimeout(() => resolve(n), n);
});
}
function step1(n) {
console.log(`step1 with ${n}`);
return takeLongTime(n);
}
function step2(m, n) {
console.log(`step2 with ${m} and ${n}`);
return takeLongTime(m + n);
}
function step3(k, m, n) {
console.log(`step3 with ${k}, ${m} and ${n}`);
return takeLongTime(k + m + n);
}
复制代码
takeLongTime起到的做用就是延时以后给出延时的数据。
step1表明第一步延时了多久。
step2表明第一步和第二部总共延时了多久。
step3表明第一步、第二步和第三步一共延时了多久。
function doIt() {
console.time("doIt");
const time1 = 300;
step1(time1)
.then(time2 => {
return step2(time1, time2)
.then(time3 => [time1, time2, time3]);
})
.then(times => {
const [time1, time2, time3] = times;
return step3(time1, time2, time3);
})
.then(result => {
console.log(`result is ${result}`);
console.timeEnd("doIt");
});
}
doIt();
复制代码
async function doIt() {
console.time("doIt");
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}`);
console.timeEnd("doIt");
}
doIt();
复制代码
在这种复杂逻辑中,咱们就能发现async/await
确实比then链有优点。
async/await是一种异步的解决方案,而koa中支持这一特性,因此,在基于koa来写服务端代码的时候,这种语法糖不可避免,学习和运用它是咱们的必修课。