2016-03-29 4 views
16

У меня есть такая ситуация, в которой я хотел бы знать, какой статус является обещанием. Ниже, функция start вызывает только someTest, если он больше не работает (обещание не ожидается). 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 было бы приятно :) Любая помощь была бы оценена!

+0

Что такое прецедент? Я не думаю, что национальные обещания поддерживают это, это странная вещь, которую нужно делать, но Blubird делает http://bluebirdjs.com/docs/api/ispending.html – elclanrs

+0

Не уверен, что вы еще не отметили Mozilla, но у них есть хорошие примеры и документация по обещаниям - https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise –

+0

В моем случае его 'setInterval' вызывает что-то async все время. И что-то должно запускаться только тогда. Я мог бы, конечно, установить переменную на 'this', например' this.isBusy = true'. Но, на мой взгляд, это звучит как обход для незнания статуса обещания. –

ответ

9

Вы можете прикрепить then обработчик, который устанавливает 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() обработчика, это важно для того, чтобы вызвать обработчика независимо от результата обещания. Возможно, вы захотите обернуть это функцией, но для того, чтобы сохранить код DRY.

+0

Я бы предположил, что было бы проще просто сделать это .promise = null' – Bergi

+1

«Пустое» аргумент 'catch' не работает. Вам все равно нужно явно передать пустую функцию, или это просто бессмысленно. – Bergi

+0

@ Bergi - хорошая точка о пустом улове, исправляя сейчас ... Что касается 'this.promise = null', это нормально для этого конкретного случая, но не столь же надежного в целом. Например, из обещания выставляется из функции, имеющей доступное на обещание имущество лучше. – Amit

1
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); 
+1

Существует недостаток, чтобы вернуть обещание после 'then()' - у вас не может быть разрешенное значение, переданное следующему обработчику. Кроме того, это не сработает, если тесты пройдут (см. Мой ответ об этом). – Amit

+1

Обратный вызов 'then' [потерял контекст методов] (http://stackoverflow.com/q/20279484/1048572) – Bergi

+0

Простите, вы, ребята, абсолютно правы. Я обновил свой код соответственно. –

Смежные вопросы