throw an error in Promise
· 2 分钟阅读
在 Promsie 中抛出异常
标题部分 在 Promsie 中抛出异常之前有一次想通过在 promise 中抛出异常,通过try catch
捕获到异常,然后实现某种逻辑。当时搜了一下,有人说用 setTimeout
,那个时候我对 event loop
、microtask & macrotask
还没有什么概念。现在我也记不得当时的问题是什么了。反正搜到一个 stackoverflow 问题。
最近了解了一下 event loop 和 microtask & macrotask 相关内容,再回顾这个问题就清除了很多。try catch
是不能捕获异步抛出的异常的…
首先定义这两个函数,返回 promise 对象:
function do1() { return new Promise((resolve, reject) => { throw new Error("do1"); setTimeout(resolve, 1000); });}
function do2() { return new Promise((resolve, reject) => { setTimeout(() => { reject(new Error("do2")); }, 1000); });}
Promise A+ 中并没有关注于如何创建 promise。但是 Chrome 中运行 do1()
返回的是一个 rejected promise。执行下面的代码:
do1() .then(do2) .catch((err) => { console.log(err.stack); throw err; });
由于在 do1() 中抛出了异常,这个 then 中的 do2 不会执行。catch 中的回掉会执行,log err.stack,根据规范,如果onRejected
中抛出了异常,则返回一个以该异常为 reason 的 rejected promise。Chrome console 会提示uncaught error in promise
。如果给包裹上 try catch
,是捕获不到错误的,为什么可以看参考链接 2。
然后看下面的代码,与上面不同之处在于 throw err
放到 setTimeout
(一个 macrotask)中了:
do1() .then(do2) .catch((err) => { console.log(err.stack); setTimeout(() => { throw err; }); });
执行之后返回的是一个 resolved promise
。error 是一个 uncaught Error
,而不是 uncaught Error in promise
。