如果我们有以下承诺,其评论中的问题答案是什么?
p.then(function ok () {
// Can we get err() to trigger from inside here?
}, function err () {
// Can we get ok() to trigger from inside here?
});
我知道可以附加新then
可以等待结果或反转p
的结果,但我想知道,假设p
是常数,是否条件也可以递归地相互调用(并且不将函数分配给变量并按名称调用它们)......
更新
我的用例如下。
在IndexedDB中,打开数据库时,您可以监听以下内容:
db.onsuccess = ...
db.onerror = ...
db.onblocked = ...
db.js,我正在扩展以满足我的需求的库,使用Promise API添加这些事件,以便成功解决承诺,错误或阻止将拒绝承诺。
监听阻塞的一个常见用例是关闭导致阻塞的数据库连接,然后IndexedDB会自动调用onsuccess
。问题是,如果我们将onblocked
视为拒绝,则显然无法重新触发解决条件(即onsuccess
)。为了解决这个问题,我可以将阻塞作为回调提供,但是我想知道是否有任何方法可以使用Promises方法专门执行它,因为从技术上讲,错误将不再是错误,并且希望通过处理成功,让原始决心回调的机会恢复。
答案 0 :(得分:2)
因为你将错误处理程序指定为.then的第二个参数,它在语义上意味着只有在承诺" p"被拒绝了。所以这两条路是相互排斥的。这也意味着,如果在你的'" ok"处理程序你抛出一个错误,它不会被" err"功能
相比之下,如果您的代码使用了.catch
,那么它会在成功处理程序中捕获来自承诺拒绝,和的错误。所以如果你有这个:
p.then(function () {
throw new Error("Within the .then");
}).catch(function (error) {
console.log(error);
});
无论p是已解决还是拒绝,它总是会将错误记录到控制台。
所以对于你的第一个问题:ok处理程序可以触发err函数,IF而不是用你做的两个参数做.then(successHandler).catch(errorHandler)。但是对于第二个问题,它没有"没有"无论如何 - 错误处理程序或" catch"都没有逻辑路径。到由于拒绝而明确跳过的路径。
根据更新的问题说明进行更新:
假设你在" catch"中得到某种指标。关于错误发生的原因(以及你是否真的应该拒绝,或者你是否应该继续,好像它是否成功),你没有理由不能像成功一样调用同样的功能。只是它有两个入口点:
p.then(successHandler, failureHandler)
.then( /* other stuff if you want to chain */ )
.catch(function(e) {
// catch-all handler just in case
})
function successHandler(data) {
// Do something. Note that to avoid
// "breaking the promise chain", the code here
// should either be all-synchronous or return another promise.
}
function failureHandler(error) {
if (error.wasDueToBlocking()) {
return successHandler(error.partialData);
} else {
// handle the true error. Again, to avoid
// "breaking the promise chain", the code here
// should either be all-synchronous or return another promise.
}
}
根据不创建独立命名函数/变量的要求更新2
我不完全确定你为什么不想要命名的功能,而我即将展示的方法可能有点奇怪。但可以想象,你可以做到这一点,相反,成功处理程序除了链接到一个实际的公共处理程序之外什么都不做。
p.then(function(data) {
return {goOn: true, data: data};
}, function(error) {
if (error.wasDueToBlocking()) {
return {goOn: true, data: error.partialData};
} else {
// Do some errorHandling logic
return {goOn: false};
}
}
.then(function(passedThroughData) {
if (passedThroughData.goOn) {
// Do something with it.
// Otherwise ignore, since error handler
// already took care of whatever it needed above
}
})
.then(function() {
// whatever you wanted to happen next
})
.catch(function(e) {
// catch-all handler just in case
})
答案 1 :(得分:2)
我们可以从
err()
触发ok
吗? 我们可以从ok()
触发err
吗?
没有。 promises spec强制要求两个then
处理程序中的一个最多被调用。如果承诺履行了第一次被调用,如果承诺拒绝第二次意愿,承诺不能同时做这两件事。
因此,虽然您可以轻松地创建两个命名函数并手动调用,但在编程方式上不能触发承诺调用另一个函数。
我的用例如下[...]
您实际上正在寻找的是
db.open().catch(function(err) {
if (err.isBlocking)
return db.closeAndWaitForNextSuccess(err.blocker); // get another promise
else
throw err;
}).then(function ok(res) {
…
});