2016-05-17 5 views
1

У меня есть некоторый код, который в основном выглядит следующим образом:Составления Обещания и без Обещания значения

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

Как вы можете видеть, f() требует foo и bar аргумента. Проблема в том, что bar является Promise. Если бы f() требуется только bar, я хотел бы сделать:

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

Однако f() требует как значение bar в результате Promise и его соответствие не-обещание foo, так что я не уверен, что это лучший способ, чтобы закодировать это ?

+0

Вашего ' обещания баров никогда не разрешаются? – Bergi

+0

@ Bergi: Упс, отредактирован. –

ответ

3

.map передает индекс элемента на обратный вызов, так что вы могли бы сделать

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

Это хорошая идея, но приведенный выше код - всего лишь образец. В фактическом коде 'foos' не входит в область обработчика' .then() ', поэтому большая часть проблемы заключается в передаче' foo' в эту область. –

+3

Это, кажется, совсем другой вопрос. 'foos' должен быть в пределах любых вызовов'. then'. Я предположил, что если 'bar' находится в сфере видимости,' foos' также. Пожалуйста, укажите лучший пример своей проблемы. –

+1

@DunPeal: Как бы 'foo' были в сфере видимости, если 'bar' не было обещанием? – Bergi

1

Если foos не в сферу действия Promise.all().then() обработчика, то вам необходимо убедиться, что foos, а также bars являются прервал цепочку обещаний.

Вот несколько подходов:

1. Доставить массив объектов

Каждый объект будет содержать foo и его соответствующий bar.

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. Deliver объект массивов

Объект будет содержать массив foos и congruant bars массив.

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), возможно, менее грязный, чем (2).

0

(Придерживаясь ограничениям, указанных в комментариях, что foos не в рамках ...)

Вы можете передать дополнительный аргумент вниз по цепочке немного Smoother с помощью ES6 деструктурирующими:

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))); 
Смежные вопросы