【问题标题】:promise cancellation still firing fulfill function承诺取消仍然触发履行功能
【发布时间】:2015-04-13 18:14:23
【问题描述】:

这是我的代码:

var promiseResult =  new BBpromise(function(resolve, reject){
    console.log(1)
    // some actions
    setTimeout(function(){
        resolve();
    }, 2000);
}).cancellable().catch(BBpromise.CancellationError, function(e){
    console.log(e);
});

promiseResult.then(function(){
    console.log('AYYYY');
});
promiseResult.cancel(new BBpromise.CancellationError()).then(function(s){
    console.log('canceled ?');
});

我得到以下输出:

顺便说一句.. 输出似乎是即时的。好像只要跳那个决心。

1
{ [CancellationError: cancellation error] __stackCleaned__: true }
AYYYY
cancelled ?

它说..“stactCleaned: true”所以我猜这意味着所有的功能都被清理了。不过好像我错了

所以我的问题:

  • 为什么当我调用 cancel() 时,如果 promise 被取消,我会在输出中看到“AYYYY”。
  • cancel 到底在做什么? 在这种情况下,cancel 到底在做什么?
  • 有没有办法取消 Promise 内容的执行或 Promise 的传播?

【问题讨论】:

    标签: javascript promise bluebird cancellation


    【解决方案1】:

    为什么当我调用 cancel() 时,如果 promise 被取消,我会在输出中看到“AYYYY”。

    这是.catch() 的常见行为。

    使用catch(),您会遇到取消错误,这会产生一个新的promise,该promise 用值undefined 解析(因为您没有从.catch() 处理程序返回任何内容)。

    所以你提供给then的函数调用就好了。

    在这种情况下取​​消实际上在做什么?

    来自 Bluebird 文档:

    取消一个 Promise 会传播到目标 Promise 的最远的可取消祖先,并以给定的原因拒绝该 Promise,或者默认为 CancellationError。

    它正在沿着承诺链上行并拒绝您创建的第一个承诺(并且您将其标记为.cancellable())。 .cancel() 最多拒绝一个承诺,而不是整个链。

    有没有办法取消promise内容的执行或者promise的传播?

    您无法取消已在运行的代码的执行,您传递给 Promise 构造函数的函数中的代码就是这种情况。

    如果解决方案尚未在承诺链中传播,您可以取消处理程序的执行。

    您可以取消 Promise 的传播。你正是这样做的。但是,如果您 catch 取消,然后将任何内容链接到 catch,您将重新开始承诺链。

    也许这会有点启发性:

    var promiseResult =  new Promise(function(resolve, reject){
        console.log(1)
        setTimeout(function(){
            resolve("1");
        }, 2000);
    }).cancellable().then(function () {
        console.log("this is never called");
        return 2;
    }).catch(Promise.CancellationError, function(e){
        console.log(e);
        return 3;
    });
    
    promiseResult.then(function(d){
        console.log("got the value " + d);
        return 4;
    });
    promiseResult.cancel(new Promise.CancellationError()).then(function(s){
        console.log("and I got the value " + s);
        return 5;
    });

    输出是:

    1
    CancellationError: ...
    got the value 3
    and I got the value 3
    

    如你所见,原来的 promise 被取消了,所以“this is never called”部分永远不会被调用。您有 catchthen 调用,它们会进一步恢复链。

    【讨论】:

    • 我对您不理解的部分的解释是“如果取消仍然触发“已填充”处理程序,那么调用取消有什么意义?”或者可能是结尾位“在这种情况下取​​消实际上在做什么?”
    • 那么被清理的栈是我在catch方法之前定义的那个?因为我的猜测是,如果我调用 cancel(),所有在取消之前定义的堆栈都应该被清理,而不仅仅是在 catch 之前定义的堆栈。
    • 是的,catch 在这里扮演的角色与同步 try .. catch 中的 catch 块相同。另请参阅:stackoverflow.com/questions/28446869/executing-then-after-catch/…,请参阅我帖子末尾的编辑。
    • 好的,现在我明白发生了什么。所以我可以说取消只是一种引发错误的方法,而不是真正的取消,并且作为 try...catch 块跳转代码工作。谢谢。
    • "它沿着 Promise 链向上移动并拒绝您创建的第一个 Promise(并且您将其标记为 .cancellable())。.cancel() 最多拒绝一个 Promise,而不是整个 Promise链。“很清楚。
    猜你喜欢
    • 2014-06-04
    • 2018-10-20
    • 1970-01-01
    • 2021-06-28
    • 1970-01-01
    • 2015-11-17
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多