Skip to main content

async/await

async/await 处理异步任务的优势:

  • 同步代码,可读性更好
  • await 会等待 Promise 完成,并返回结果
  • 可以通过 try-catch 捕获异常
async function getUser() {
const user = await getUser();
return user;
}
getUser().then((res) => console.log(res));

async

执行 async 函数

  • 无论在什么情况下,一定会返回 Promise 实例对象。如果函数原先返回的不是 promise 对象,会自动用 Promise.resolve 包裹并返回
  • 函数执行过程中抛出错误,则返回的 Promise 实例对象的状态将改变为 rejected

await

  • 正常情况下,await 命令后面是一个 Promise 实例对象。如果不是,会被转成一个立即 resolved 的 Promise 实例对象
  • await 命令后面的 Promise 实例对象如果变为 rejected 状态,则 reject 的参数会被 catch 方法的回调函数接收到
  • 只要一个 await 语句后面的 Promise 实例对象变为 rejected 状态,那么整个 async 函数都会中断执行。可以利用 try-catch 包裹异常的 await,避免中断

实现原理

async/await 其实是 Generator 的语法糖,参考以下例子:

// generator 自动执行器
function getNumPromise(num) {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve(num);
}, 1000);
});
}

function* getNum() {
const f1 = yield getNumPromise(1);
const f2 = yield getNumPromise(f1 + 1);
return yield getNumPromise(f2 + 1);
}

function run(gen) {
// 生成一个迭代器
const g = gen();

function next(data) {
let result = g.next(data);
if (result.done) {
return result.value;
}
result.value.then((data) => {
console.log(data);
next(data);
});
}

next();
}

run(getNum);

可以通过 babel 查看转译 async 后的结果,其实跟上面内容差不多的