当前位置:  开发笔记 > 编程语言 > 正文

如何取消Javascript Promise内部的超时?

如何解决《如何取消JavascriptPromise内部的超时?》经验,为你挑选了2个好方法。

我正在使用JavaScript中的promises并试图宣传setTimeout函数:

function timeout(ms) {
  return new Promise(function(resolve, reject) {
    setTimeout(function() {
      resolve('timeout done');
    }, ms);
  }); 
}

var myPromise=timeout(3000); 

myPromise.then(function(result) { 
  console.log(result); // timeout done
})

相当简单,但我想知道如何在诺言结算之前取消我的超时.timeout返回Promise对象因此我松开了对setTimeout返回值的访问权限,并且无法通过取消超时clearTimeout.最好的方法是什么?

顺便说一句,这没有真正的目的,我只是想知道如何处理这个问题.我也把它放在这里http://plnkr.co/edit/NXFjs1dXWVFNEOeCV1BA?p=preview



1> PSL..:

您可以做什么,您可以从您的timeout函数返回一个取消器,并在需要时调用它.这样您就不需要存储timeoutid全局(或外部作用域),也可以管理对函数的多个调用.函数返回的每个对象实例timeout都有自己的取消器,可以执行取消.

function timeout(ms) {
  var timeout, promise;

  promise = new Promise(function(resolve, reject) {
    timeout = setTimeout(function() {
      resolve('timeout done');
    }, ms);
  }); 

  return {
           promise:promise, 
           cancel:function(){clearTimeout(timeout );} //return a canceller as well
         };
}

var timeOutObj =timeout(3000); 

timeOutObj.promise.then(function(result) { 
  console.log(result); // timeout done
});

//Cancel it.
timeOutObj.cancel();

Plnkr



2> Benjamin Gru..:

然而,PSL的答案是正确的 - 有一些警告,我会做的有点不同.

超时被清除意味着代码不会运行 - 所以我们应该拒绝承诺.

在我们的例子中,返回两件事是没有必要的,我们可以在JavaScript中修补补丁.

这里:

function timeout(ms, value) {
  var p = new Promise(function(resolve, reject) {
    p._timeout = setTimeout(function() { resolve(value); }, ms);
    p.cancel = function(err){ 
      reject(err || new Error("Timeout")); 
        clearTimeout(p._timeout); // We actually don't need to do this since we
                                  // rejected - but it's well mannered to do so
    }); 
  return p;
}

哪个让我们这样做:

var p = timeout(1500)
p.then(function(){
     console.log("This will never log");
})

p.catch(function(){
     console.log("This will get logged so we can now handle timeouts!")
})
p.cancel(Error("Timed out"));

人们可能对完全取消感兴趣,实际上一些图书馆直接支持这作为图书馆的一个功能.事实上,我敢说大多数人都这样做.但是,这会导致干扰问题.从这里引用KrisKowal :

我取消的立场已经发生了变化.我现在确信使用Promise抽象取消(bg:传播)本质上是不可能的,因为promises可以随时引入多个dependess和dependees.如果任何家属取消承诺,它将能够干扰未来的家属.有两种方法可以解决这个问题.一种是引入单独的取消"能力",也许作为论据传递.另一种是引入一种新的抽象,一种可能是可行的"任务",它可以取代每个任务只有一个观察者(一个随后就可以调用),而不必担心干扰.任务将支持fork()方法来创建新任务,允许另一个dependee保留任务或推迟取消.


虽然我无法在任何地方找到它,但Promise的"定居者"函数似乎在同一个事件中运行,因为`var p = new Promise()`,因此你不能在定居者里面引用`p` .解决方案(至少是我能想到的唯一一个)相当丑陋而且有效 - [DEMO](http://jsfiddle.net/9bnjevvu/).
@ Benjamin-Gruenbaum有更好的答案.如果您向承诺添加成员,那么您将无法从依赖承诺中取消(即.then()结果); 有关详细信息,请参阅[本文](https://blog.codecentric.de/en/2015/03/cancelable-async-operations-promises-javascript/)
推荐阅读
echo7111436
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有