Promises 允许我们通过 then 中的错误处理模块或者 catch 模块来处理错误。Async/await 有相近的策略。
await 与 catch 一起使用
我们使用 await 一个异步的函数,通常情况下 await 操作符是与 Promise 一起使用的,而且只能再 async 函数内部。Async 函数提供了 promises 所以我们就可以使用 catch 块来处理异常。
const myPromise = async () => {
return new Promise((resolve, reject) => {
setTimeout(() => {
reject("We ran into an error");
}, 2000);
});
}
const main = async () => {
const response = await myPromise().catch((err) => {
console.log(err); // We ran into an error
})
}
main();
myPromise 2秒钟后 reject 并打印出一条信息,当我们在等待 promise 结果的时候,我们可以在其后增加 catch 来处理错误。
当调用 async 函数时,使用 catch
当我们调用 async 函数时,可以在其后添加 catch。
const myPromise = async () => {
return new Promise((resolve, reject) => {
setTimeout(() => {
reject("We ran into an error");
}, 2000);
});
}
const main = async () => {
const response = await myPromise();
}
main().catch((err) => {
console.log(err); // We ran into an error
});
因为 main 是一个 async 函数且返回一个 promise ,所以我们可以使用 catch 连一起。使用 catch 不错但有一个缺点,它会捕获所有错误而不单单是 myPromise 引起的。
使用高阶函数
我们可以使用 catch 来捕获错误,但假设你项目中有许多 async 函数,为每一个添加 catch 会令人厌烦但你有不得不加,该怎么办?
这时候就需要使用高阶函数,它就是把一个函数作为输入然后输出另一个函数。
const myPromise = async () => {
return new Promise((resolve, reject) => {
setTimeout(() => {
reject("We ran into an error");
}, 2000);
});
}
const main = async () => {
const response = await myPromise();
}
const handleError = (err) => {
console.log(err); // We ran into an error
}
const addingErrorHandler = (fn, errorHandler) => {
return function() {
fn().catch(errorHandler);
}
}
const mainFunctionWithErrorHandler = addingErrorHandler(main, handleError);
mainFunctionWithErrorHandler();
我们添加了三个新方法:
- handleError 为一个标准的错误处理函数。
- addingErrorHandler 为一个高阶函数,一个函数作为入参同时为该函数添加错误处理。
- mainFunctionWithErrorHandler 为 main 函数经过高阶函数处理后能处理异常的函数。
因为例子仅仅处理了一个 main 函数,你可能会感觉添加太多的函数。但我们可以在大项目中通过高阶函数处理不计其数的 async 函数。
使用 try/catch 函数
JavaScript 为我们添加了 try/catch 快来处理异常,同样可以应用在 async/await 上:
const myPromise = async () => {
return new Promise((resolve, reject) => {
setTimeout(() => {
reject("We ran into an error");
}, 2000);
});
}
const main = async () => {
try {
await myPromise(); // try this code
} catch (err) { // if it throws an error execute the catch block
console.log(err); // We ran into an error
}
}
main();
try/catch 是最简单易懂的方式,但在大型项目中我还是喜欢使用高阶函数来处理 async/await 的异常。