Javascript NodeJS Promise all接受任务队列中的所有承诺
我正在尝试创建一个函数,该函数将获得一系列承诺,并分块执行这些承诺 这里我有一个我写的函数的例子,它本应该实现我想要的。 但是现在发生的是,所有的承诺在第一个承诺之后都已经执行了。 nodeJS调试器显示其工作方式与我所希望的一样。但是我可以看到whireshark中的所有请求都是在第一个块之后发送的Javascript NodeJS Promise all接受任务队列中的所有承诺,javascript,node.js,promise,async-await,chunks,Javascript,Node.js,Promise,Async Await,Chunks,我正在尝试创建一个函数,该函数将获得一系列承诺,并分块执行这些承诺 这里我有一个我写的函数的例子,它本应该实现我想要的。 但是现在发生的是,所有的承诺在第一个承诺之后都已经执行了。 nodeJS调试器显示其工作方式与我所希望的一样。但是我可以看到whireshark中的所有请求都是在第一个块之后发送的 const reqs = [...Array(10)].map(() => () => axios.post('http://localhost:7000/test', {}))
const reqs = [...Array(10)].map(() => () => axios.post('http://localhost:7000/test', {}))
const handleChunks = (reqs) => {
const chunks = []
const chunkSize = 5
for (let i = 0; i < reqs.length; i += chunkSize) {
chunks.push(reqs.slice(i, i + chunkSize))
}
chunks.reduce(async (acc, chunk) => {
const chunkToPromise = chunk.map((chunkFunc) => chunkFunc())
return Promise.all(chunkToPromise).then(async (result) => {
acc = await acc
acc.push(result)
return acc
})
}, Promise.resolve([]))
}
const-reqs=[…数组(10)].map(()=>()=>axios.post('http://localhost:7000/test', {}))
常量handleChunks=(需求)=>{
常量块=[]
常量chunkSize=5
for(设i=0;i{
const chunkToPromise=chunk.map((chunkFunc)=>chunkFunc())
返回Promise.all(chunkToPromise).then(异步(结果)=>{
acc=等待acc
acc.push(结果)
返回acc
})
},Promise.resolve([]))
}
在我看来,我正在创建的所有承诺都已经在任务队列中声明了自己,并且承诺。所有承诺并不是真的接受了你给他的承诺,而是接受了任务队列中的所有承诺
有人知道如何处理这种问题吗
编辑:我发现在客户机上也是如此……这里有三个方面,将承诺分块,运行分块,然后等待它们全部完成。让我们创建一些帮助程序:
// NOTE: works but probably not optimal. I fired this off the top of my head,
// for something like this in production I'd use a library function from
// lodash or ramda or something.
const partition = (n, xs) => {
const results = [];
let i = k = 0;
while (i < xs.length) {
results.push([]);
while (k < n) {
if (i === xs.length) break;
results[results.length - 1].push(xs[i]);
i++;
k++;
}
k = 0;
}
return results;
};
// This will make the requests from the passed in array and
// wait for them all to finish. Note that unlike Promise.all
// allSettled will not bail early if you get a rejection.
const runPromiseFns = async (ps) => Promise.allSettled(ps.map(x => x()));
// This will take an array of arrays of Promise generating functions
// and wait for each sub-array to settle before moving on
// to the next one.
const runChunks = async (chunks) => {
for (let chunk of chunks) {
await runPromiseFns(chunk);
}
return;
};
您对问题的描述与您发布的代码非常不同,这使得它很难理解。特别是,根本不清楚您的阵列切片是否按照您期望的方式工作,或者您期望通过分块(不是用一堆请求向服务器发送垃圾邮件?)实现什么。你说的“任务队列”是什么意思,因为我没有看到你,例如从堆栈中弹出任何内容?我对你的问题的最好解释是,你想向服务器发出
n
请求,但一次只运行k
个请求,等待当前的k
请求集完成,然后继续下一步。是吗?是的,杰瑞德你是对的。。如果我不够清楚,很抱歉。所以Jared首先感谢您的快速回复。看起来你的解决方案是有效的。但它在我的环境中不起作用。经过几次实验后,我发现我的环境中的问题是,我使用的是NODE js version 10.14->it,这个版本中似乎有一个bug。我在版本12+中尝试了相同的代码,效果很好
// Array of request thunks from your original code
const reqs = [...Array(10)].map(() => () => axios.post('http://localhost:7000/test', {}));
// Break into chunks of 5
const chunks = partition(5, reqs);
// Run through the execution pipe. Here allDone is a
// Promise you can .then or await somewhere else.
const allDone = runChunks(chunks);
const promiseAllFn = (pollingRequests) => Promise.all(pollingRequests.map((pollingRequest) => callApi(pollingRequest)));
chunk(Object.values(subRegister), 4).reduce(
(prev, pollingRequests) => prev.then(() => promiseAllFn(pollingRequests)),
Promise.resolve('start')
);