async/await 在JavaScript中作为AsyncFunction的关键字,是ES7提出的基于promise解决js中异步问题的所谓终极方案。其实是Generator函数的语法糖。
在使用async/await 之前,需要知道这个关键字在ie全系列浏览器都是不支持的,具体如下。
1、字面意思
根据命名来粗略的进行理解:
async:异步;
await: 是async wait的缩写,可以理解成等待异步的意思。
2、实际含义
async:函数的修饰符,用于声明该函数是一个异步函数(基于promise的),会默认返回Promise对象,如果该函数有返回值,则会调用Promise.reslove()方法将返回值进行reslove,所以对于async函数也可以直接调用then方法。
注:如果该函数没有返回值,则会resolve一个undefined。
async function tryAsync(){
return 'I`m Async';
}
const testResult = tryAsync();
console.log(testResult); // 输出一个状态为fullfield的Promise对象
tryAsync().then(res=>{
console.log(res); // I`m Async
})
await:也是修饰符,只能放在async定义的函数内。
await在等什么?通俗来讲,await后面修饰的内容,即为await等待的东西,可以是一个Promise,也可以是任意其他的表达式。
有什么区别呢?如果它等的不是一个 Promise 对象,那 await 表达式的运算结果就是它等到的东西。如果是一个 Promise 对象,它会阻塞后面的代码(仅async内部的代码),等着 Promise 对象 resolve,然后得到 resolve 的值,作为 await 表达式的运算结果,如果Promise无法reslove而是进行了rejected,那么可以用try catch对await进行处理。
async function fun() {
let a = await "a";
let b = await new Promise((resolve, reject) => {
setTimeout(function () {
resolve("b");
}, 2000);
});
let c;
try {
c = await new Promise((resolve, reject) => {
setTimeout(function () {
reject("c");
}, 2000);
});
} catch {
c = "err";
}
let d = await (function () {
return "d";
})();
console.log(a, b, c, d);
}
fun();
console.log(123);
3、为什么async/await是处理异步的终极方案
简单比较下async/await 和 Pormise的区别
function timeMachine(second) {
return new Promise((resolve) => {
setTimeout(() => resolve(second), second * 1000);
});
}
// promise
timeMachine(1).then((res) => {
console.log(res);
});
// async/await
async function tryTimeMachine() {
let res = await timeMachine(1);
console.log(res);
}
tryTimeMachine();
这个时候会发现,普通的promise调用语法甚至更简洁,但是当出现了多个Promise组成的链式调用时,async/await就能展示出他的优势。
// 需要链式调用多个promise时候
function checkNumber(n) {
return new Promise((resolve, reject) => {
setTimeout(() => {
if (n < 3) resolve({ status: true, data: n + 1 });
else reject({ status: false, data: n + 1 });
}, 1000);
});
}
// 1、写在then里
checkNumber(1).then((res) => {
console.log(res);
checkNumber(res.data).then((res) => {
console.log(res);
checkNumber(res.data)
.then((res) => {
console.log(res);
})
.catch((err) => {
console.log(err);
});
});
});
// 2、链式调用
function commonCheck(n) {
return checkNumber(n);
}
function doCommonCheck(n) {
commonCheck(n)
.then((res) => commonCheck(res.data))
.then((res) => commonCheck(res.data))
.then((res) => console.log(`结果:${JSON.stringify(res)}`))
.catch((err) => {
console.log(err);
});
}
doCommonCheck(1);
// 3、async/await
async function asyncCommonCheck(n) {
const res1 = await checkNumber(n);
const res2 = await checkNumber(res1.data);
let res3;
try {
res3 = await checkNumber(res2.data);
} catch {
res3 = "error";
}
console.log(`结果:${JSON.stringify(res3)}`);
}
asyncCommonCheck(1);
除此之外,如果需要同时处理多个异步的返回结果,可以使用Promise.all()
// 同时需要处理多个promise
async function allAsync1(db) {
let arr = [1, 2, 3];
let promises = arr.map((doc) => checkNumber(doc));
let results = await Promise.all(promises);
console.log(results);
}
allAsync1();
//
async function allAsync2(db) {
let arr = [1, 2, 3];
let promises = arr.map((doc) => checkNumber(doc));
let results = [];
for (let promise of promises) {
results.push(await promise);
}
console.log(results);
}
allAsync2();