我有一些基本上看起来像这样的代码:
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()
需要由Promise
及其匹配的非承诺foo
产生的bar
值,所以我不确定编码这一点的最佳方式是什么?
.map
也将元素的索引传递给回调,因此可以执行
Promise.all(bars).then(
values => values.map((value, i) => f(foos[i], value))
);
如果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)));
演示
2.交付阵列对象
该对象将包含一个foos
数组和一个一致的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])));
演示
(1) 可以说没有(2)那么混乱。
(遵守评论中提到的foos
不在范围内的限制…)
您可以使用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)));