运行promise.all of promise.alls

时间:2018-05-16 16:13:06

标签: javascript node.js promise

我正在向服务器发出400个请求 - 并将每个请求放在承诺中。

在单个promise.all中运行所有400个请求时 - 系统崩溃。

我已经将我的请求分成了50个承诺(并将它们添加到promise.all中),并将所有这些添加到另一个promise.all中。

如何批量运行承诺,等待进入下一个承诺?

// attach the other accounts a user has to the wrapper object
// **this is 400+ requests object, that has the requests in it**
// results are promises
const influencerAccounts = wrapper.map(p => addInfluencerAccounts(p));

// split the requests into chunks to stop the server falling over
const chunkedPromises = _.chunk(influencerAccounts, 50);

// promise.all on each chunk of promises/requests
// ????


// ...

return

我已尝试循环遍历分块承诺数组(这是一系列承诺)和Promise.all(ing)每一个 - 但是它不会等到上一批完成之前完成发送下一个。

谢谢,

奥利

1 个答案:

答案 0 :(得分:1)

你犯了很多的人犯了一个错误:Promise.all没有运行任何东西。它只是等待已经运行的东西。当你将influencerAccounts阵列分解成块时,你可能已经超载了服务器,因为你仍然在同时发送400多个请求。

相反,将payout数组块化,然后以块为单位进行处理,这些内容如下:

const results = [];
const promise =
    _.chunk(payout, 50).reduce(
        (p, chunk) =>
            p.then(chunkResults => {
                results.push(...chunkResults);
                return Promise.all(chunk.map(startRequest)); 
            })
        ,
        Promise.resolve([])
    )
    .then(() => results);

我上面使用的是startRequest而不是createInfluencerWrapperaddInfluencerAccounts因为我不清楚你是否介绍了其中一个试图进行分块工作。但如果没有,startRequest只是addInfluencerAccounts(createInfluencerWrapper(entry))

启动50个请求的大块,使用Promise.all等待所有请求完成,然后启动下一个50个请求。 “当它完成时执行此操作”部分来自 promise reduce 成语,其简单形式如下所示:

someArray.reduce((p, entry) => p.then(() => doSomethingWith(entry)), Promise.resolve());

它以一个已解决的promise开始,并在其上挂钩then处理程序以执行下一步操作,它挂接上的then处理程序以执行下一项操作等等。

如果您不喜欢关闭results,我们可以将其传递到reduce链;这是上面的第一个版本:

const promise =
    _.chunk(payout, 50).reduce(
        ({p, results}, chunk) => ({
            p: p.then(chunkResults => {
                results.push(...chunkResults);
                return Promise.all(chunk.map(startRequest)); 
            }),
            results
        }),
        {p: Promise.resolve([]), results: []}
    )
    .then(({results}) => results);