2017-11-03 2 views
0

Ich habe eine Liste von asynchronen Funktionen. Ich habe erwartet, wenn die allererste Funktion auflösen (oder ablehnen), kann ich andere stoppen.Wie blockiert man andere Versprechen nach einem Ende

Beispiele:

function wait(ms){ 
    return new Promise(function(resolve){ 
     setTimeout(function(){ 
      console.log('waited ', ms); 
      resolve(); 
     }, ms); 
    }) 
} 

promise1 = wait(2000); 
promise2 = wait(5000); 

listPromise = [promise1, promise2]; 

Promise.race(listPromise).then(function(){ 
    console.log("Very first promise has resolved!"); 
}) 

Das tatsächliche Ergebnis ist:

> waited 2000 
> Very first promise has resolved! 
> waited 5000 

Das erwartete Ergebnis ist:

> waited 2000 
> Very first promise has resolved! 
+1

Wenn das erste Versprechen löst, tun Sie * abbrechen zu wollen * die Ausführung der anderen Versprechungen und möglicherweise Bereinigung durchführen, oder tun Sie don einfach‘ Ich möchte, dass sie die Rückrufmethode aufrufen, aber ihre Ausführung wird fortgesetzt, obwohl Sie sich nicht um ihren Rückgabewert kümmern? Bitte lesen Sie [diese Antwort] (https://stackoverflow.com/questions/30233302/promise-is-it-possible-to-force-cancel-a-promise#30235261), was sehr gut erklärt, wie man mit beiden Situationen umgeht. – Svenskunganka

Antwort

0

Versprechungen sind nicht voneinander unabhängige Prozesse, die abgebrochen oder gestoppt werden kann. Wenn in einem von ihnen ein Timer läuft, wird es dies weiterhin tun, wenn Sie es nicht selbst stoppen.

Um Ihr spezielles Problem zu lösen, müssen Sie die Zeitüberschreitungen überwachen, die gerade ausgeführt werden, und alle anderen Zeitüberschreitungen löschen, sobald das erste Problem gelöst ist.

So etwas sollte funktionieren:

var timeoutIds = []; 

function wait(ms){ 
    return new Promise(function(resolve){ 
     var timeoutId = setTimeout(function(){ 
      console.log('waited ', ms); 
      resolve(); 
     }, ms); 
     timeoutIds.push(timeoutId); 
    }) 
} 

promise1 = wait(2000); 
promise2 = wait(5000); 

listPromise = [promise1, promise2]; 

Promise.race(listPromise).then(function(){ 
    console.log("Very first promise has resolved!"); 

    for (var i = 0; i < timeoutIds.length; i++) { 
     clearTimeout(timeoutIds[i]); 
    } 
}) 
+0

Danke für die Lösung, aber ich meine alle asynchronen Funktionen, nicht nur bestimmte setTimeout. Ich habe die Antwort in der Referenz von Svenskunkanka gefunden. – LittleZero

+0

@LittleZero, Ja, diese Lösung ist speziell für Timeouts gedacht, aber für andere Operationen wäre es ähnlich. Sie würden eine Instanz beispielsweise für die Abrufoperation beibehalten und "cancel" darauf aufrufen. –

1

Sie können einen Token an Ihre Versprechen senden sie später aufzuheben.

function wait(ms, token){ 
 
    return new Promise(function(resolve){ 
 
     var t = setTimeout(function(){ 
 
      console.log('waited ', ms); 
 
      resolve(); 
 
     }, ms); 
 
     token.cancel = function(){ 
 
      clearTimeout(t); 
 
     } 
 
    }) 
 
} 
 

 
var tokens = [{},{},{}]; 
 

 
promise1 = wait(3000,tokens[0]); 
 
promise2 = wait(2000,tokens[1]); 
 
promise3 = wait(5000,tokens[2]); 
 

 
listPromise = [promise1, promise2,promise3]; 
 

 
var p = Promise.race(listPromise).then(function(){ 
 
    console.log("Very first promise has resolved!"); 
 
    for(var i = 0; i< listPromise.length; i++) 
 
     tokens[i].cancel(); 
 
})

Hier arbeitet Link: https://jsfiddle.net/Lwymeoz0/

Verwandte Themen