2016-03-29 30 views
16

Ho questa situazione in cui vorrei sapere qual è lo stato di una promessa. Sotto, la funzione start chiama solo someTest se non è più in esecuzione (Promise non è in sospeso). La funzione start può essere chiamato molte volte, ma se la sua chiamata, mentre i test sono ancora in funzione, non la sua intenzione di aspettare e restituisce solo falseCome verificare se una promessa è in sospeso

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 
     }); 
    } 
} 

non riesco a trovare un modo per verificare semplicemente lo stato di una promessa. Qualcosa come this.promise.isPending sarebbe carino :) Qualsiasi aiuto sarebbe apprezzato!

+0

Qual è il caso d'uso? Non credo che le promesse native supportino questo, è una cosa strana da voler fare, ma Blubird fa http://bluebirdjs.com/docs/api/ispending.html – elclanrs

+0

Non sono sicuro se hai già controllato Mozilla, ma hanno buoni esempi e documentazione sulle promesse - https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise –

+0

Nel mio caso è un 'setInterval' che chiama qualcosa di asincrono tutto il tempo. E quel qualcosa dovrebbe funzionare solo uno alla volta. Ovviamente potrei impostare una variabile su 'this', come' this.isBusy = true' per esempio. Ma a mio parere, sembra una soluzione per non conoscere lo stato di una promessa –

risposta

9

È possibile allegare un gestore then che imposta una bandiera done sulla promessa (o l'istanza RunTest se preferite), e verificare che:

 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; 
    } 

Avviso del catch() gestore vuota, è fondamentale al fine di far chiamare il gestore indipendentemente dall'esito della promessa. Probabilmente vorrai completarlo in una funzione per mantenere il codice ASCIUTTO.

+0

Direi che sarebbe più facile fare semplicemente 'this.promise = null' – Bergi

+1

Un argomento" vuoto "' catch' non funziona. Hai ancora bisogno di passare esplicitamente una funzione vuota, o è solo priva di significato. – Bergi

+0

@Bergi - buon punto sul fermo vuoto, correggendo ora ... Per quanto riguarda 'this.promise = null', va bene per questo caso specifico, ma non altrettanto robusto in generale. Ad esempio, la promessa è esposta al di fuori della funzione, avendo la proprietà disponibile sulla promessa è più bello. – 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

C'è uno svantaggio nel restituire la promessa dopo 'then()' - non è possibile avere un valore risolto passato al gestore successivo. Inoltre, questo non funzionerà se i test vengono lanciati (vedi la mia risposta a riguardo). – Amit

+1

Il 'then' callback [ha perso il contesto dei metodi] (http://stackoverflow.com/q/20279484/1048572) – Bergi

+0

Siamo spiacenti, voi ragazzi siete completamente corretti. Ho aggiornato il mio codice di conseguenza. –