2017-10-05 1 views
0

bewegt habe ich eine Anforderung folgendes zu tun:JavaScript Promises - für die Auflösung warten, bevor auf

  1. Hier finden Sie eine Liste der „Linien“ durch eine interne Funktion aufrufen (getLines()).
  2. die erste Zeile auswählen, führt eine Aktion
  3. nach der vorherige Aktion beendet ist, die nächste Zeile ausgewählt und für alle Linien, die die gleiche Aktion
  4. Repeat tun (3-20 je nach Benutzer)

ich habe den folgenden Code anstelle:

App.Lines = response.data;  
for (var _i = 0; _i < App.Lines.length; _i++) { 
    var makeCallPromise = new Promise(
     function(resolve, reject) { 
      Session.connection.ol.makeCall(App.Lines[_i], callBackFunction(response) { 
       //this can take up to 30 seconds to respond... 
       resolve(response.data); 
      }, errorCallBackFunction(message) { 
       reject(message.error); 
      }, bareJid); 
     } 
    ) 
    makeCallPromise.then(function(fulfilled) { 
     console.log("PROMISE WORKED!!!!!", fulfilled); 
    }) 
    .catch(function(error) { 
     console.log("PROMISE FAILED!!!!!", error); 
    }); 
} 

Meine Hoffnung war, dass die Schleife, das Versprechen zu lösen würde warten, bevor sie die Schleife fortgesetzt, aber das ist nicht der Fall. Meine Frage ist, ob es möglich ist, die Schleife anzuhalten, bis die Auflösung abgeschlossen ist. Hinweis - Ich verwende die Bluebird JS-Bibliothek für Versprechungen. Vielen Dank!

Mit freundlichen Grüßen,

Gary

+0

Ich denke, dass Sie müssen 'das Versprechen in irgendeiner Weise return'. Wie in diesem Fall ist "erfüllt" das Schlüsselwort, das Sie in Ihrem Versprechen verwenden. – ZombieChowder

+0

Anstatt die gesamte Sache zu loopen, mach makeCallPromise eine Schleife und schiebe diese Versprechen an ein Array. Dann verwenden Sie Promise.all (Array) und fügen Sie die 'then()' Aufrufe nach dem provect.all hinzu. Das Ergebnis wird sein, dass alle Vorhersagen aufgelöst werden, bevor das erste 'then()' aufgerufen wird, so dass alle Daten erneut durchlaufen werden können.Alternativ verwenden Sie keine Schleife, sondern machen die nächste makeCallPromise, nachdem die erste verrechnet wurde. – Shilly

+0

@Shilly Danke, ich habe versucht, dies in der Antwort von marvel308 mit Promise.each() zu verwenden. Meine Antwort ist, was ich getan habe und was passiert ist. – Gary

Antwort

0

Sie Promise.each() von drossel vorgesehen nutzen können, Es wäre ein Array durchqueren seriell und warten, bis sie, bevor er auf das nächste Element in der Matrix zu lösen

+0

Ich habe versucht, indem ich über die Versprechungen iterieren und ein Array von ihnen erstellen (anstatt sie in der Iteration aufzulösen). Ich habe dann 'Promise.each (proveyArray, function (result) {console.log (result)}} aufgerufen, dann (function (filled) {console.log ("WORKED")}). Catch (function (error) { console.log ("FEHLER")})); '. Das Problem ist, dass dies nicht funktioniert, es versucht immer noch, sowohl Session.connection.ol.makeCall zu tun, ohne auf die erste zu warten. – Gary

+0

Haben Sie Bluebird verwendet? – marvel308

+0

Hmm Ich habe die Bluebird-Bibliothek geladen, indem Sie es in

0

I Ich weiß nichts über Bluebird, aber Sie können so etwas tun, um eine Art for-Schleife zu erstellen, die darauf wartet, dass jedes Versprechen vor der nächsten Iteration endet.

Hier ist ein allgemeines Beispiel, ist es sicherlich optimiert werden könnte, es ist nur ein kurzer Versuch:

var i = 0; 
var performAsyncOperation = function(operationNumber) { 
    return new Promise(function(resolve, reject){ 
    console.log('Operation number', operationNumber); 
    resolve(); 
    }); 
} 

var chainAsyncOperations = function() { 
    if(++i < 10) { 
     return performAsyncOperation(i).then(chainAsyncOperations); 
    } 
}; 
performAsyncOperation(i).then(chainAsyncOperations); 

der Hoffnung, das wird Ihnen helfen,)

0

Diese Use Case paßt perfekt zum ES7 Merkmale async await, wenn Sie die Möglichkeit haben, Ihren Code mit babeljs transpile, könnten Sie Ihre Funktion wie diese Refactoring:

function createPromise(line) { 
    return new Promise(
     function(resolve, reject) { 
      Session.connection.ol.makeCall(line, callBackFunction(response) { 
       //this can take up to 30 seconds to respond... 
       resolve(response.data); 
      }, errorCallBackFunction(message) { 
       reject(message.error); 
      }, bareJid); 
     } 
    ); 
} 

App.Lines = response.data; 

async function main() { 
    for (var _i = 0; _i < App.Lines.length; _i++) { 
     try { 
      var result = await createPromise(App.Lines[_i]); 
      console.log(result); 
     } catch (err) { 
      console.log(err); 
     } 
    } 
} 

main().then(function() { 
    console.log('finished'); 
}); 
0

sollten SieverwendenMethode:

.each (function (jedes Element, int index, int length) Iterator) -> Versprechen

Iterate über ein Array oder ein Versprechen eines Arrays, das Versprechen (oder a enthält Mischung von Versprechungen und Werten) mit der gegebenen Iteratorfunktion mit der Signatur (Wert, Index, Länge), wobei Wert der aufgelöste Wert eines jeweiligen Versprechens im Eingabearray ist. Die Iteration erfolgt seriell. Wenn eine Zusage im Eingabe-Array zurückgewiesen wird, wird das zurückgegebene Versprechen ebenfalls zurückgewiesen.

Promise.each(App.Lines, line => { 
    return new Promise((resolve, reject) => { 
     Session.connection.ol.makeCall(line, callBackFunction(response) { 
      resolve(response.data); 
     }, errorCallBackFunction(message) { 
      reject(message.error); 
     }, bareJid); 
    }) 
    .then(fulfilled => console.log("PROMISE WORKED!!!!!", fulfilled)) 
    .catch(err => onsole.log("PROMISE FAILED!!!!!", err)); 
}); 
+0

Hallo, das funktioniert nicht, ich verstehe nicht wirklich, was es macht. In einem einfachen Fall von 1 Line-Wert sieht es so aus, als würde es zweimal im gleichen Moment 'Session.connection.ol.makeCall' ausgeben, sodass wir sofort einen Fehler bekommen. Wenn ich dies auf 2 Zeilen aktualisiere, gibt es 4 'Session.connection.ol.makeCall' in einem Moment aus und später gibt es 2 weitere, nachdem die Antwort zurückkommt. – Gary

+0

Laut dem Code in Ihrer Frage, 'App.Lines' ist ein Array von Zeilen, in meinem Code verwende ich' Bluebird # eachly' Methode, um über dieses Array zu iterieren und 'Session.connection.ol.makeCal' für jede Zeile aufzurufen. Sind Sie sicher, dass 'App.Lines' im ersten Fall eine Zeile (ein Element) und im zweiten Fall zwei Zeilen hat? Fügen Sie 'console.log (App.Lines.length)' vor 'Promise.each' hinzu. – alexmac

Verwandte Themen