【问题标题】: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是否挂起看起来并不“奇怪”,它似乎是绝对基础的。

标签: javascript promise ecmascript-6 es6-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);

【讨论】:

猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-06-21
  • 2018-03-31
  • 1970-01-01
  • 2023-03-03
  • 2020-09-06
  • 1970-01-01
相关资源
最近更新 更多