2016-07-27 23 views
5

Ich habe ein Skript wie:javascript Promise.all letzte Versprechen gibt nur

var a = [{'a': 1},{'b': 2}] 
var allPromises = new Array(a.length) 
for(var i in a) { 
    allPromises[i] = Promise.resolve().then(response => { 
     console.log(i) 
     console.log(a[i]) 
     // Do somethig on every loop with key and value 
     return i 
    }) 
} 

Promise.all(allPromises).then(response => console.log(response)) 

Hier in meinem for loop es gibt mir nur letzte Index und den Wert des letzten Index, während ich den Wert auf jeder Schleife und führen einige wollen Aktion mit Schlüssel und Wert .. Aber ich bekomme den letzten Schlüssel und Wert nur ..

Ich versuchte, den Wert auf Promise.all Antwort, aber nicht funktioniert. Wie kann ich den Index meines Arrays auf die allPromises Antwort bekommen?

Ich kann es tun, indem ich einen Zähler mache. Aber wenn ich die Funktion erneut anrufe, wird der Zähler zurückgesetzt, also möchte ich den Zähler nicht benutzen.

Gibt es sowieso ich kann Index für jede Schleife für Versprechen bekommen?

+1

Die Verwendung von 'let' anstelle von' var' würde auch mit der Art und Weise funktionieren, wie die for-Schleife geschrieben wird, weil 'let' mit Block-Scoping funktioniert, nicht nur mit der Funktion scoping. Aber ich würde auch die Lösung von @ jfriend00 bevorzugen, da meiner Meinung nach die 'Array.map' /' Array.forEach' besser lesbar ist. –

+1

Sie haben bereits einige gute Antworten, also brauchen Sie keine anderen :) Aber um eine weitere Option zu dem Mix hinzuzufügen: Da Sie bereits die Auflösung verwenden, können Sie 'i' hineingeben, so dass es dann der Parameter innerhalb' 'wird '(' resolve') und verwende diesen Parameter anstelle der äußeren 'i'-Variable: https: // jsfiddle.net/vscbgwpm/ –

+1

Die Verwendung von 'var' ist hier ein typischer JS-Scoping-Hinterhalt. Sie sollten 'let' anstelle von' var' verwenden. Oder die Idee von @ Me.Name ist auch ziemlich gültig und gut. – Redu

Antwort

8

Ihre i Variable in der Handler in Ihrem for Schleife ist nicht, was Sie denken, dass es ist. Ihre for-Schleife wurde bereits vollständig ausgeführt, bevor einer Ihrer .then()-Handler aufgerufen wird (da sie bei einem zukünftigen Tick immer asynchron ausgeführt werden). Sie denken also nur, dass Sie das letzte Versprechen sehen, aber tatsächlich funktionieren alle Versprechen gut, es ist nur so, dass sie alle den letzten Wert von i zurückgeben.

Sie können es reparieren, indem Sie .forEach() verwenden, um Ihr Array zu iterieren, da es jeden Wert von i eindeutig erfasst.

var a = [{'a': 1},{'b': 2}] 
 
var allPromises = new Array(a.length); 
 
a.forEach(function(item, i) { 
 
    allPromises[i] = Promise.resolve().then(response => { 
 
     console.log(i) 
 
     console.log(a[i]) 
 
     // Do somethig on every loop with key and value 
 
     return i 
 
    }) 
 
}); 
 

 
Promise.all(allPromises).then(response => console.log(response))

Oder, da Sie ein Array als Folge sind zu erzeugen, könnten Sie .map() verwenden:

var a = [{'a': 1},{'b': 2}] 
 
var allPromises = a.map(function(item, i) { 
 
    return Promise.resolve().then(response => { 
 
    console.log(i) 
 
    console.log(a[i]) 
 
    // Do somethig on every loop with key and value 
 
    return i 
 
    }) 
 
}); 
 

 
Promise.all(allPromises).then(response => console.log(response))

+0

Das ist genau das erste, was mir nach dem Lesen der Post in den Sinn kam. –

+0

funktioniert wie Charme :) – gamer

+0

Sie könnten sogar ersetzen "forEach" mit einer 'map' -Funktion und wandeln jeden Eintrag in eine Zusage für diesen Eintrag. Dies würde dann vermeiden, vorher ein leeres Array zu initialisieren. –

0

ich glaube, das Versprechen ist alles cool, aber es ist schade dir gesagt zu haben, dass du falsch liegst. dies ist ein Versprechen, alle Demo:

var p = []; 
 
p[0] = new Promise((resolve, reject) => { 
 
    setTimeout(resolve, 1000, "one"); 
 
}); 
 
p[1] = new Promise((resolve, reject) => { 
 
    setTimeout(resolve, 1000, "two"); 
 
}); 
 
p[2] = new Promise((resolve, reject) => { 
 
    setTimeout(resolve, 2000, "three"); 
 
}); 
 
p[3]= new Promise((resolve, reject) => { 
 
    setTimeout(resolve, 3000, "four"); 
 
}); 
 
p[4] = new Promise((resolve, reject) => { 
 
    setTimeout(resolve, 4000, "done"); 
 
}); 
 

 
Promise.all(p).then(value => { 
 
    console.log(value); 
 
});

so denke ich, Ihr Code wie folgt aussehen wird:

var arr = [{ a: 1 }, { b: 2 }]; 
 
var p = []; 
 
arr.forEach((val, err) => { 
 
    var promiseFunction = new Promise((resolve, reject) => { 
 
    resolve(val); 
 
    }); 
 
    p.push(promiseFunction); 
 
}) 
 

 
Promise.all(p).then(value => { 
 
    console.log(value); 
 
});

was denken Sie?