在bluebird中,同时执行多个promise数组

时间:2017-05-20 15:44:28

标签: javascript promise bluebird

我想做这样的事情:

given:
a = [a bunch of promises]
b = [another bunch of promises]
c = [more promises]

do:
return Bluebird.all(a, b, c).spread((resolved_a, resolved_b, resolved_c) => {
  // do stuff
})

这似乎不起作用。 Promise.all在给出多个单独的承诺或一系列承诺时工作正常。

谢谢!

@Andy Gaskell,

使用点差版本,我没有得到我想要的行为。 给出:

a = an array with three promises that resolve to 'a', 'b', and 'c'
b = like a but resolves 'd', 'e', 'f'
d = like a but resolves 'g', 'h', 'i'

return Bluebird.all(a, b, c,).spread((ra, rb, rc) => {
  console.log(ra) // 'a', 'b', 'c'
  console.log(rb) // 'd', 'e', 'f'
  console.log(rc) // 'g', 'h', 'i'
}

我想在.then()中保持已解析的promises分开。传播或收缩数组使它们变得扁平化,因此将已解决的数据组合成一个数组。

也许这是不可能的?

@tincot

你的方法几乎就在那里,已经解决的承诺结构完美,但似乎并不(我认为,还没有完全说服自己)同时执行。

2 个答案:

答案 0 :(得分:2)

使用Array.concatspread创建新阵列。

concat版本看起来像这样:

Bluebird.all(a.concat(b).concat(c))

传播版本:

Bluebird.all([...a, ...b, ...c])

答案 1 :(得分:1)

就像您的数组是嵌套的一样,您也可以嵌套.all次调用。

这里有本地承诺,但与蓝鸟相同:

const a = [Promise.resolve('a'), Promise.resolve('b'), Promise.resolve('c')]; 
const b = [Promise.resolve('d'), Promise.resolve('e'), Promise.resolve('f')]; 
const c = [Promise.resolve('g'), Promise.resolve('h'), Promise.resolve('i')]; 

Promise.all([a, b, c].map(x => Promise.all(x))).then(responses => {
    console.log(responses); // [["a","b","c"],["d","e","f"],["g","h","i"]]
});
.as-console-wrapper { max-height: 100% !important; top: 0; }

所有承诺将立即创建,最终承诺将在最后一个原始承诺解决时解决。以下是上述代码段的变体,用于说明:

const delayed = (ms, val) => new Promise( resolve => setTimeout(_ => resolve(val), ms) );

var a = [delayed( 500, 'a'), delayed( 700, 'b'), delayed( 300, 'c')]; 
var b = [delayed( 200, 'd'), delayed(1000, 'e'), delayed( 800, 'f')]; 
var c = [delayed( 600, 'g'), delayed( 900, 'h'), delayed( 400, 'i')]; 

Promise.all([a, b, c].map(x => Promise.all(x))).then(responses => {
    console.log(responses); // [["a","b","c"],["d","e","f"],["g","h","i"]]
});

setTimeout(_ => console.log('all should be resolved'), 1050);
.as-console-wrapper { max-height: 100% !important; top: 0; }