如何检查 Promise 是不是处于待处理状态 [重复]

Posted

技术标签:

【中文标题】如何检查 Promise 是不是处于待处理状态 [重复]【英文标题】:How to check if a Promise is pending [duplicate]如何检查 Promise 是否处于待处理状态 [重复] 【发布时间】:2016-07-17 14:06:04 【问题描述】:

我有这种情况,我想知道一个承诺的状态。下面,函数start 仅在不再运行时调用someTest(Promise 未挂起)。 start 函数可以被多次调用,但如果在测试仍在运行时调用它,它不会等待并返回 false

class RunTest 
    start() 
         retVal = false;

         if (!this.promise) 
             this.promise = this.someTest();
             retVal = true;                
         

         if ( /* if promise is resolved/rejected or not pending */ ) 
             this.promise = this.someTest();
             retVal = true;
         

         return retVal;
    

    someTest() 
        return new Promise((resolve, reject) => 
            // some tests go inhere
        );
    

我找不到简单检查承诺状态的方法。像this.promise.isPending 这样的东西会很好:) 任何帮助将不胜感激!

【问题讨论】:

用例是什么?我不认为原生承诺支持这一点,这是一件很奇怪的事情,但 Blubird 支持 bluebirdjs.com/docs/api/ispending.html 不确定你是否已经检查过 Mozilla,但他们有很好的例子和关于 Promise 的文档 - developer.mozilla.org/en-US/docs/Web/javascript/Reference/… 在我的例子中,setInterval 一直在调用异步的东西。而且那个时候应该只运行一个。我当然可以在this 上设置一个变量,例如this.isBusy = true。但在我看来,这听起来像是一个不知道承诺状态的解决方法 mozilla 页面确实很棒,但是没有关于如何检查promise 状态的内容。如果我错过了,请告诉我们! 检查一个promise是否挂起看起来并不“奇怪”,它似乎是绝对基础的。 【参考方案1】:

您可以附加一个then 处理程序,该处理程序在promise 上设置done 标志(或RunTest 实例,如果您愿意),并测试:

     if (!this.promise) 
         this.promise = this.someTest();
         this.promise.catch(() => ).then(() =>  this.promise.done = true; );
         retVal = true;                
     

     if ( this.promise.done ) 
         this.promise = this.someTest();
         this.promise.catch(() => ).then(() =>  this.promise.done = true; );
         retVal = true;
     

注意空的catch() 处理程序,无论promise 的结果如何,都必须调用处理程序。 您可能希望将其包装在一个函数中以保持代码干燥。

【讨论】:

我想这样做会更容易this.promise = null “空”catch 参数不起作用。您仍然需要显式传递一个空函数,否则它只是没有意义。 @Bergi - 关于空捕获的好点,现在更正......关于this.promise = null,对于这种特定情况来说可以,但一般来说没有那么强大。例如,promise 暴露在函数之外,promise 上的属性可用更好。 当然,但通常没有人希望在 Promise 上使用这样的属性,所以没有必要公开它。在您认为需要确定 Promise 状态的所有情况下,您真正​​需要的是检查您的回调是否已被调用。 FWIW,可以考虑用 .finally() 替换 .catch(() => ).then()【参考方案2】:
class RunTest 
   constructor() 
    this.isRunning = false;
   
   start() 
      console.log('isrunning', this.isRunning);
      var retVal = false;
      if(!this.isRunning) 
        this.promise = this.someTest();
        this.promise.catch().then(() =>  this.isRunning = false; );
        retVal = true;                
      
      return retVal;
    
    someTest() 
        this.isRunning = true;
        return new Promise((resolve, reject) => 
          setTimeout(function() 
             //some tests go inhere
             resolve();
           , 1000);
        );
    
;

var x = new RunTest();

x.start(); //logs false
x.start(); //logs true

setTimeout(function() 
    //wait for a bit
  x.start(); //logs false
, 2000);

【讨论】:

then () 之后返回promise 有一个缺点——您不能将已解析的值传递给下一个处理程序。此外,如果测试抛出,这将不起作用(请参阅我的回答)。 then 回调has lost the methods context jsfiddle.net/tchalvakspam/wszyqj3t/3

以上是关于如何检查 Promise 是不是处于待处理状态 [重复]的主要内容,如果未能解决你的问题,请参考以下文章

如何检查系统是不是处于待机模式?

检查数据块记录是不是处于编辑或添加状态

为啥我得到 Promise 待处理而不是 Express 响应? [复制]

如何检查对象是不是处于空状态?

为啥 Amazon Sandbox 订单始终处于待处理状态?

简单的 AJAX Get 请求处于“待处理”状态