一个 promise resolver/rejecter 可以触发它的对立面吗?

Can a promise resolver/rejecter trigger its opposite?

如果我们有如下承诺,其评论中问题的答案是什么?

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 方法来做到这一点,因为从技术上讲,错误将不再是错误并且想要让原始解析回调有机会恢复其对成功的处理。

因为您将错误处理程序指定为 .then 的第二个参数,所以它在语义上意味着它只会在承诺 "p" 被拒绝时触发。所以这两条路是互斥的。这也意味着如果在 "ok" 处理程序中抛出一个错误,它不会被 "err" 函数捕获。

相比之下,如果您的代码使用了 .catch,它会从成功处理程序中捕获从 promise 拒绝中冒出的错误 。所以如果你有这个:

p.then(function () {
    throw new Error("Within the .then");
}).catch(function (error) {
    console.log(error);
});

它总是将错误记录到控制台,无论 p 是否已解决或拒绝。

所以对于你的第一个问题:ok 处理程序 可以 触发 err 函数,如果不是做 .then 有两个参数你做 .then(successHandler).catch(errorHandler) .但是对于第二个问题,无论如何都是 "no"——从错误处理程序或 "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 以不创建名为 function/variables

的独立文件

我不完全确定您为什么不想要命名函数,而且我将要展示的方法可能有点奇怪。但是可以想象你可以这样做,相反,成功处理程序除了链接到一个实际的通用处理程序之外什么都不做。

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
 })

Can we get err() to trigger from ok?
Can we get ok() to trigger from err?

没有。 promises spec 要求最多调用两个 then 处理程序中的一个。如果 promise 实现第一个遗嘱,如果 promise 拒绝第二个遗嘱,一个 promise 不能同时做这两件事。

因此,虽然您可以轻松创建两个命名函数并手动相互调用,但无法以编程方式触发 promise 调用另一个函数。

My use case is as follows […]

您实际上要寻找的是

db.open().catch(function(err) {
    if (err.isBlocking)
        return db.closeAndWaitForNextSuccess(err.blocker); // get another promise
    else
        throw err;
}).then(function ok(res) {
    …
});