async 与 await - 你不知道的 JS

  1. asyuc 的函数
  2. await
  3. 错误处理

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 正常 resolveawait 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


转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论。
我的空间