const promise = new Promise(function (resolve) {
resolve('ok');
// setTimeout(function () {
throw new Error('test');
// }, 0);
});
promise.then(console.log);
注释去掉之后则可以
Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号
1.首先你要明白一个
promise有三种状态,分别是pending,resolved(alias: fulfilled) 和rejected。 而且一旦状态改变,就不会再变,任何时候都可以得到这个结果。状态改变只有两种可能:从pending变为resolved和从pending变为rejected。只要这两种情况发生,状态就凝固了,不会再变了,会一直保持这个结果。2.当你注释掉你的setTimeout之后代码就变成了
上面的
resolve('ok')已经将Promise的状态变成了resolved, 你再throw error是不会被捕获的。3.为什么加了
setTimeout之后就可以了捕获了,因为你加了setTimeout之后, 是指定到下一轮“事件循环”再抛出错误,将冒泡到最外层,成了未捕获的错误。因为此时,Promise已经resolved了,完成了自己的任务,所以这个错误是在Promise函数体外抛出的。 你这个时候抛错误出来会被进程捕获并丢出来的。Supplement from @haidao17 :
4.解释并改造你的三段代码说明一下
4-1. 下面例子中
throw Error会被promise的catch方法捕获!4-2. 下面例子中
throw Error被忽略!!!!等价于没有抛出错误4-1和4-2说明了Promise的状态一旦改变就是永久的改变,一直保持这个状态,之后是无法再改变的。
4-3. 下面例子中
throw Error会被process捕获!运行一下上面三段代码,然后你自己稍微再体会一下!!希望对你有帮助。
我不知道
promise()过后Promise都干了什么,但是我认为resolve()和reject()是互斥的,一个运行了另一个就不运行了。另外,如果在 Promise 回调中抛出异常,是会被封装成
reject()调用的,需要通过.catch(callback)来捕捉。所以,上面,在注释的情况下,已经
resovle()了,后面的throw被封装成的reject()调用就被忽略了,所以没有抛出错误。问题在于把
throw放在setTimeout里之后,估计reject()不能把setTimeout()的回调封住,所以错误被直接抛出来了,而且不能被.catch()到,因为它已经脱离了 Promise 的控制。是不是因为Promise内部的错误不会冒泡的全局,所以需要使用setTimeout方法包装一下?