如何解决NodeJS Promise 全部从任务队列中获取所有承诺
我正在尝试创建一个函数,该函数将获取一组 promise 并分块执行它们。
这里我有一个我写的函数的例子,它应该能完成我想要的。 但是发生的事情是所有的承诺都已经在第一个 promise.all 之后执行了。 nodeJS 调试器显示它按我希望的那样工作。但是我可以在whireshark中看到所有请求都是在第一个块之后发送的。
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([]))
}
在我看来,我创建的所有 Promise 都已经在任务队列中声明了自己,而 Promise.all 并没有真正接受你给他的东西,而是任务队列中的所有承诺>
有人知道如何处理这种问题吗?
编辑:我发现在客户端上的工作方式相同......
解决方法
这里有三个方面,对 Promise 进行分块,运行分块,并等待它们全部完成。让我们创建一些助手:
// 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;
};
太好了。现在:
// 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')
);
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。