wake-up-neo.com

Wie mache ich diese async foreach Schleife mit Versprechen?

Ich habe schon mit Versprechungen herumgespielt, aber ich bin neu bei ihnen und ich kann einfach nicht herausfinden, wie ich es richtig mache. Im Moment hat das Versprechen keinen Sinn, weil es nicht wartet, bis der async $.get abgeschlossen ist.

Grundsätzlich hat jede foreach-Iteration ihre eigene $.get-Funktion, und ich muss sie alle vollständig haben und dann mit dem Teil fortfahren, der den "... gets albumart" console.log enthält.

$.get(id,function(data) {
    //(there's some code here)
    var getZippyUrls = new Promise(function(resolve) {
            zippyarray.forEach(function(zippy) {
            //(more code)
            $.get(zippy.full, function(data) {
                //^This is the foreach of $.gets
               //(code's here)
            });  
           resolve(zippyarray);
        });
    });

    //This is my failed Promise ->
    getZippyUrls.then(function(response) {
        console.log("WE'RE OUT " + response.length);
        response.foreach(function(d) {
            console.log("Promise"+d.media);
        });
        console.log('eyyyyyy');
    });

    console.log("...gets albumart");
    //Now after the previous stuff is done, move on
15
Fabis

Im synchronen Code wird eine Fortsetzung durchgeführt, wenn die Zeile endet. ; 

Bei Versprechen erfolgt die Fortsetzung über .then. Sie haben einen Versprechenkonstruktor verwendet und ihn sofort gelöst, Sie haben auf keine Aufgabe gewartet. Ich würde meine Arbeit in Aufgaben einordnen und sie dann entweder verketten oder seriell abwarten.

//I'm assuming
zippyarray; // array of Zippy objects

var tasks = zippyarray.map(function(zippy,i){
    return function(){ // return a task on that zippy;
       // basic logic here
       return $.get({
            // ajax request
       }).then(function(data){
            // process data like in your code
            // possibly store later for later use too
            return process(data); // return the processed data;
       });
    }
});

Jetzt können wir sie alle sequentiell ausführen:

 var p = tasks[0](); // start the first one
 for(var i = 1; i < tasks.length; i++) p = p.then(tasks[i]);
 p.then(function(result){
       // all available here
 });

Oder besser seriell:

$.when.apply(tasks.forEach(function(t){ return t(); })).then(function(results){
     // all done
})
20

Ich weiß, dass dies eine alte Frage ist, aber die Dinge haben sich in letzter Zeit etwas geändert.

Wenn Sie mit der Verwendung externer Bibliotheken zufrieden sind, bietet die Versprechenbibliothek Bluebird eine ziemlich gute Implementierung dafür: Promise.each .

Z.B.

function helperFunc(zippyarray) {
  return Promise.each(zippyarray, zippy => {
    return someOperationThatReturnAPromise(zippy)
      .then((singleResult) => {
        // do something with the operation result if needed
      })
  }).then((originalArray) => {
    // this happens only after the whole array is processed
    // (result is the original array here)
    return Promise.resolve(originalArray)
  })
}
10
MJV

Um mehrere get-Requests zu verfolgen, verwenden Sie diesen Weg:

var cnt = requestCnt;

function finished(){
    if(--cnt)return;
    // Your code here
}

for(var i = 0; i < requestCnt; ++i){
    $.get('something.htm', {data:data}, function(data){
        finished();
    });
}

Sie rufen immer die finish-Funktion auf, wenn eine Anfrage beantwortet wird. Die Fertig-Funktion erledigt die Arbeit, wenn alles erledigt ist.

0
Fuzzyma

Wenn ich es heute nacheinander machen müsste, würde ich das mit async/await machen:

//I'm assuming I'm inside an `async` function
zippyarray; // array of Zippy objects

for(const task of zippyArray) {
  const result = await $.get({ ... });
  // do stuff with result
}
0