当Parse for React Native中的一系列promise中抛出异常时,我注意到发生了一些非常奇怪的事情。承诺链永远不会解决,永远不会拒绝,并且永远不会抛出异常。它只是默默地消失。
以下是重新创建问题的示例代码:
// Replacing this with Promise.resolve() prints the error.
// Removing this stage prints the error.
Parse.Promise.as()
// Removing this stage causes a red screen error.
.then(function() {
// Replacing this with Parse.Promise.as() causes a red screen error.
return Promise.resolve();
})
.then(function () {
throw new Error("There was a failure");
})
.then(function () { console.log("Success")}, function (err) { console.log(err) });
从评论中可以看出,它似乎只发生在这个特定的事件序列中。删除一个阶段,或者交换一个原生JS承诺的Parse承诺,会导致事情再次发生。 (在我的实际代码中," Promise.resolve()"阶段实际上是对返回promise的本机iOS方法的调用。)
我知道Parse承诺不会像A +兼容的承诺那样完全(参见https://stackoverflow.com/a/31223217/2397068)。实际上,在此部分代码之前调用Parse.Promise.enableAPlusCompliant()
会导致异常被捕获并打印。但我认为Parse promises和原生JS承诺可以安全地一起使用。
为什么这个异常会无声地消失?
谢谢。
答案 0 :(得分:0)
除了您在引用答案中提供的技术原因之外,还需考虑您的考虑事项:
ES6 / A +兼容的Promise实例共享:
then
注册的监听器在导致它们执行的代码运行完成后,在自己的线程中异步执行。无论听众是否因为承诺被解决而被注册(“已履行”或“被拒绝”),
then
注册所返回的承诺throw
)用于拒绝then
注册返回的承诺,使用Promise实例解析的promise与自身的最终结算状态和作为参数提供的promise的值同步。 (在ES6标准中,这被描述为“锁定”)。
不合规承诺的潜在特征包括对象
then
返回的promise。 Promise.resolve
可用于通过静态值来解决其返回的promise,可能主要用于测试。然而,它的主要目的是隔离不合规承诺的副作用。 Promise.resolve( thenable)
返回的承诺将展示上述所有行为1-7,并且不会出现任何违规行为。
恕我直言我建议只在环境中使用非A + promise对象,并根据创建它们的库的文档。非兼容的thenable可用于直接解析A + promise(这是Promise.resolve所做的),但是为了完全可行的行为可预测性,它应该在任何其他用途之前使用Promise.resolve( thenable)
包装在Promise对象中。 / p>
注意我试图测试Parse承诺的A +合规性,但它似乎没有提供构造函数。这使得“几乎”或“完全”A +合规性的主张难以量化。感谢zangw指出可能会将拒绝的承诺作为一个侦听器返回,作为抛出异常的替代方法。
答案 1 :(得分:0)
为什么这个异常会消失?
Parse默认情况下不会捕获异常,并且promises会吞下它们。
Parse不是100%Promises / A +兼容,但它确实试图吸收从then
回调返回的那些。它既不会捕获异常,也不会异步执行自己的回调。
您可以在没有then
使用
var p1 = new Parse.Promise();
var p2 = new Parse.Promise();
// p2 should eventually settle and call these:
p2._resolvedCallbacks = [function (res) { console.log("Success") }];
p2._rejectedCallbacks = [function (err) { console.log(err) }];
function handler() {
throw new Error("There was a failure");
}
// this is what the second `then` call sets up (much simplified):
p1._resolvedCallbacks = [function(result) {
p2.resolve(handler(result)); // throws - oops
}];
// the native promise:
var p = Promise.resolve();
// what happens when a callback result is assimilated:
if (isThenable(p))
p.then(function(result) {
p1.resolve(result);
});
问题是p1.resolve
是同步的,并立即执行p1
上的回调 - 这反过来会抛出。通过在可以调用p2.resolve
之前投掷,p2
将永远等待。异常冒泡并成为p1.resolve()
的完成 - 现在抛出回调到本机then
方法。本机promise实现捕获异常并拒绝then
使用它返回的承诺,但是无处不在。
默默地?
如果您是" native" promise实现支持未处理的拒绝警告,您应该能够在被拒绝的承诺中看到异常。