在bluebird中,并发执行多个promise数组

In bluebird, execute multiple promise arrays concurrently

我想做这样的事情:

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() 中将已解决的承诺分开。扩展或收缩数组会使它们变平,因此将已解决的承诺组合到一个数组中。

也许这不可能?

@tincot

您的方法就快完成了,已解决的承诺结构完美,但似乎(我认为,还没有完全说服自己)并发执行。

使用Array.concat or spread创建一个新数组。

concat 版本如下所示:

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

传播版本:

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

就像你的数组是嵌套的,所以你也可以嵌套 .all 调用。

这里用的是native promises,bluebird也是一样的:

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; }