2016-05-17 13 views
1

ich einen Code haben, der im Wesentlichen wie folgt aussieht:Composing Versprechen und nicht-Versprechen Werte

let foos = ['foo', 'foo', 'foo']; 
let bars = foos.map(foo => new Promise(resolve => resolve(foo + ' processed'))); 
function f(foo, bar) { '...' }; 

Wie Sie sehen können, erfordert f() ein foo und ein bar Argument. Das Problem ist, dass bar ein Promise ist. Hatte f() nur bar erforderlich, ich tun würde:

Promise.all(bars).then(values => values.map(f)); 

jedoch f() erfordert sowohl die bar Wert aus der Promise und seine passende nicht-Versprechen foo, also bin ich nicht sicher, was der beste Weg, dies zu codieren ?

+0

Ihre ' Bars Versprechen werden nie gelöst? – Bergi

+0

@Bergi: Whoops, bearbeitet. –

Antwort

3

.map gibt den Index des Elements auch auf den Rückruf, so könnten Sie

Promise.all(bars).then(
    values => values.map((value, i) => f(foos[i], value)) 
); 
+0

Dies ist eine gute Idee, aber der obige Code ist nur ein Beispiel. Im eigentlichen Code liegt 'foos' nicht im Bereich des '.then()' Handlers, also besteht ein großer Teil des Problems darin, den 'foo' in diesen Bereich zu übergeben. –

+3

Das scheint dann eine ganz andere Frage zu sein. '' foos' 'muss in den Bereich von, was auch immer' genannt wird. Ich nahm an, dass, wenn "Bars" in Reichweite sind, auch "Foos" ist. Bitte geben Sie ein besseres Beispiel für Ihr Problem an. –

+1

@DunPeal: Wie würden die 'foo's im Umfang sein, wenn' bar' kein Versprechen wäre? – Bergi

1

tun Wenn foos in ihrem Umfang nicht der Promise.all().then() Handler ist, dann müssen Sie sicherstellen, dass foos sowie bars sind lieferte die Versprechenskette herunter.

Hier ein paar Ansätze:

1. ein Array von Objekten liefern

Jedes Objekt enthält eine foo und seine bar entspricht.

let foos = ['foo', 'foo', 'foo']; 
let promises = foos.map(foo => new Promise(resolve => resolve({ 
    unprocessed: foo, 
    processed: foo + ' processed' 
}))); 
// ... 
Promise.all(promises).then(results => results.map(obj => f(obj.unprocessed, obj.processed))); 

Demo

2. ein Objekt von Arrays

Das Objekt einen foos-Array und einen congruant bars Array enthält liefern.

let foos = ['foo', 'foo', 'foo']; 
let promise = Promise.all(foos.map(foo => new Promise(resolve => resolve(foo + ' processed')))) 
    .then(bars => ({ 'unprocessed': foos, 'processed': bars })); 
// ... 
promise.then(obj => obj.unprocessed.map((foo, i) => f(foo, obj.processed[i]))); 

Demo

(1) ist wohl weniger chaotisch als (2).

0

(die Beschränkung in den Kommentaren erwähnt Befolgend dass foos in ihrem Umfang nicht ist ...)

Sie das zusätzliche Argument übergeben können unten in der Kette ein wenig glatten ES6 Destrukturierung mit:

let foos = ['foo', 'foo', 'foo']; 
let bars = foos.map(foo => new Promise(res => res([foo, foo + ' processed']))); 
Promise.all(bars).then(values => values.map(([foo, bar]) => f(foo, bar)));