我们一般写 Promise 时,通常会有两种方式来处理 Promise 的异常:
- 使用
catch
方法来捕获异常; - 使用
try catch
来捕获异常;
链式调用:
fetch("/api")
.then((data) => {})
.catch((err) => {
console.error(err);
});
使用try catch
来捕获异常:
const fn = async () => {
try {
const data = await fetch("/api");
} catch (err) {
console.error(err);
}
};
现在 JS 的语言标准规范 ECMAScript 近日提出了一个新提案:“安全赋值运算符”。使用 ?=
运算符将函数的结果转为元数组来简化错误处理,返回的结构为 [error, value]
。
如果函数抛出错误,则运算符返回 [error, null]
;如果函数执行成功,则返回[null, result]
。
const fn = async () => {
const [err, response] ?= await fetch("/api");
if (err) {
console.error(err);
return;
}
return response;
}
ECMAScript 的安全赋值运算符提案,受到了 Go、Rust 和 Swift 等语言中类似结构的启发,旨在通过引入新的运算符来简化代码中的错误处理逻辑,减少对传统 try-catch
代码块的依赖,从而使代码更加干净、高效且易于维护。
- 新的安全赋值运算符(如 ?=)通过将函数的结果转换为元组([错误, 结果])来减少代码的嵌套深度,使得错误处理更加直观和易于理解。
- 在处理异步代码时,这一运算符可以与
Promises
和async/await
无缝协作,使异步代码中的错误处理变得直接且高效。 - 通过统一的返回元组模式,该运算符保持了错误处理方式的一致性,降低了错过关键错误的风险。
- 减少了代码的复杂性和深度嵌套,使得代码更加线性且易于跟踪。
npm 上目前也已经有类似的库:await-to-js。
import to from "await-to-js";
const fn = async () => {
const [err, response] = await to(fetch("/api"));
if (err) {
console.error(err);
return;
}
return response;
};
不过这次 ECMA 官方打算将其加入到标准里了。
新的安全赋值运算符提案,有的同学喜欢,有的同学不喜欢。喜欢这种方式的,可以减少对try-catch
的依赖,降低代码的层级,逻辑上提前结束。而不太不喜欢的,比如经常写 Go 语言的同学,就经常吐槽该语言的 error 的处理方式。
对前端同学来说,实际上是多了一种开发的方式,喜欢用哪种、或者习惯用哪种,就用哪种方式。