拒绝并终止对外部事件的承诺

时间:2018-08-15 14:03:51

标签: javascript asynchronous promise

如果发生外部事件,我希望能够拒绝并停止其余的诺言。这是示例用例:

new Promise((resolve,reject)=>{
    websocket.onerror=reject;
    //do processing here
    websocket.onerror=undefined;
    resolve(...);
});

这具有预期的效果,如果在运行诺言时发生错误,则拒绝诺言。但是,问题在于即使发生拒绝,其余的诺言也将继续运行。

完全不能使用async / await。

我认为一种方法是将每一行代码放在单独的promise中,并取消事件链,但这会很痛苦。

2 个答案:

答案 0 :(得分:1)

  

但是,问题是即使发生拒绝,其余的诺言也将继续运行。

这是一个基本的误解(而且您并不孤单!)。没有“承诺的其余部分”。许诺只是观察完成异步过程的一种手段。持续的过程是过程,而不是承诺。

如何取消该过程(以及是否可以取消)完全取决于该过程是什么以及它是否提供了取消该过程的方法,这与承诺本身无关。您似乎正在使用Web套接字,因此您需要使用Web套接字API取消您正在执行的任何操作(或向另一端发送消息以告知其停止正在执行的操作)。

例如:假设诺言正在等待计时器(setTimeout)触发,并会在何时触发。然后发生其他事情,而您不再想要那个。拒绝诺言只是拒绝诺言,它对计时器没有任何影响。您也需要取消计时器(clearTimeout)。


重新编辑:

  

我认为一种方法是将每一行代码放在单独的promise中,并取消事件链,但这会很痛苦。

否,promise执行程序(您通过new Promise传递的函数)中的代码是同步运行的。同样,没有“其余代码”可以取消。那里可能有异步回调,或者代码启动的过程中也需要发送取消,但这并不需要将每一行都放在自己的承诺中,而不是完全没有。

答案 1 :(得分:1)

了解this question的答案可能会帮助您:

创建承诺时,它会同步执行。因此,执行以下行:

websocket.onerror=reject;

这时,您的代码开始处理。如果发生websocket错误事件,则会将其放入js事件循环,但是您的promise仍将同步执行。然后解开websocket的错误处理程序,然后解决。即使有错误,诺言也会解决。此时,对resolve的调用也已添加到js的事件循环中。然后执行下一个js滴答,也许拒绝(也许不是)被调用,但是此时并不重要,因为您是同步解决的,并且诺言一旦解决或被拒绝就永远不会改变主意。

因此,这里的关键要点是创建一个诺言会同步执行它。您不能在等待其他事件时取消该线程。许诺的解决方案或拒绝是异步执行的,但这对您完全没有帮助。

要取消承诺,您需要一些非常基本的东西,例如

if(someOtherVariableThatDeterminesCancelation){
  reject()
}