async与await-你不知道的JS
Async/await 是以更舒适的方式使用 promise 的一种特殊语法,同时它也非常易于理解和使用。
asyuc的函数
async关键字,要放在函数前面:
async function f1() {
return 1;
// return Promise.resolve(1);
}
async function f2() {
return
}
async function f3() {
return new Promise((resolve, rekected) => {
resolve("OK");
});
}
console.log(f1()); // Promise { 1 }
console.log(f2());// undefined
console.log(f3()); //Promise { <pending> }
“async” 这个单词表达了一个简单的事情:函数总是返回一个promise。
显式返回的非promise值将自动被包装在一个 resolved 的 promise 中。
await
关键字 await
让 JavaScript 引擎等待直到 promise
完成(settle)并返回结果。
在非
async
函数中使用await
的话,就会报语法错误
// async函数内
let value = await a promise;
下面的代码执行到let result = await promise
,等待promise执行完resolve后,才会继续向下执行alert。
async function f() {
let promise = new Promise((resolve, reject) => {
setTimeout(() => resolve("done!"), 1000)
});
let result = await promise; // 等待,直到 promise resolve (*)
alert(result); // "done!"
}
f();
暂停async函数执行时,JavaScript引擎会转去吃力其他脚本代码任务。
相比多个then的链式调用,使用await的写法看上去更优雅。
使用await可以做到Python里sleep函数那种效果,阻塞代码执行一定时间
(async (time) => {
console.log(1);
await new Promise((resolve, reject) => {
setTimeout(resolve, time);
})
console.log(2); //3s后打印2
})(3000);
包裹匿名函数,是因为await不能直接用在顶层代码中。
错误处理
如果一个promise
正常 resolve
, await promise
返回的就是其结果。但是如果 promise 被reject
,它将 throw
这个 error
,就像在这一行有一个 throw
语句那样。
async function f() {
await Promise.reject(new Error("Whoops!"));
}
等同于:
async function f() {
throw new Error("Whoops!");
}
这个Error可以使用try...catch
进行捕获,就像捕获常规的throw抛出的错误。
可以用 try 包装多行await
代码,一旦有任一error
,执行控制权马上移交catch
块:
如果我们没有 try..catch
块,那么由异步函数f()
的调用生成的 promise
将变为 rejected
。
我们可以在函数调用后面添加 .catch
来处理这个 error
async function f() {
let response = await fetch('http://no-such-url');
}
// f() 变成了一个 rejected 的 promise
f().catch(alert); // TypeError: failed to fetch // (*)
如果我们忘了在这添加 .catch ,那么我们就会得到一个未处理的 promise error(可以在控制台中查看)。我们可以使用在 使用 promise 进行错误处理 一章中所讲的全局事件处理程序unhandledrejection 来捕获这类 error