如何以组的方式调用一个异步函数?
How can I call one asynchronous function in a group way?
很抱歉,我可能无法清楚地描述这个问题。我试试:
现在我有一个异步函数,它接受数据并做一些事情,例如
function myFunction(num: number):Promise<void> {
return new Promise((resolve) => {
console.log(num);
return;
});
}
我想在一组中打印5个数字(顺序无关紧要)。重要的是,我想在前一组完成后打印接下来的5个数字。例如:
1, 2, 5, 4, 3, 6, 9, 8, 7, 10 ... is valid
7, 10, 1, 2, 3, 4, 5, 6, 8, 9 ... is not valid
如果我必须使用这个函数,我怎么才能使它发生?我必须确保这个函数的前五个调用已经解决,然后再调用后面的五个函数。我知道这看起来很奇怪,我试着把我现在的问题抽象成这个数字问题。
感谢您的意见和建议。
您可以通过将数组分解为块并使用Array#map
和Promise#all
处理块来实现这一点。然后可以使用Array#reduce
:
runChunkSeries([1, 2, 3, 4, 5, 6, 7, 8, 9, 10], 5, someAsyncFn);
// our placeholder asynchronous function
function someAsyncFn(value) {
return new Promise((resolve) => {
setTimeout(resolve, Math.random() * 5000);
}).then(() => console.log(value));
}
function runChunkSeries(arr, chunkSize, fn) {
return runSeries(chunk(arr, chunkSize), (chunk) => Promise.all(chunk.map(fn)));
}
// Run fn on each element of arr asynchronously but in series
function runSeries(arr, fn) {
return arr.reduce((promise, value) => {
return promise.then(() => fn(value));
}, Promise.resolve());
}
// Creates an array of elements split into groups the length of chunkSize
function chunk(arr, chunkSize) {
const chunks = [];
const {length} = arr;
const chunkCount = Math.ceil(length / chunkSize);
for(let i = 0; i < chunkCount; i++) {
chunks.push(arr.slice(i * chunkSize, (i + 1) * chunkSize));
}
return chunks;
}
使用async
/await
其实很简单:
(async function() {
var i = 0;
while (true) {
for (var promises = []; promises.length < 5; ) {
promises.push(myFunction(i++));
}
await Promise.all(promises);
}
}());
我会使用生成器,或者因为你正在使用typescript,你可以使用es7 async/await语法,使用lodash你可以做这样的事情:
(async function(){
const iterations: number = 2;
const batchSize: number = 5;
let tracker: number = 0;
_.times(iterations, async function(){
// We execute the fn 5 times and create an array with all the promises
tasks: Promise[] = _.times(batchSize).map((n)=> myFunction(n + 1 + tracker))
await tasks // Then we wait for all those promises to resolve
tracker += batchSize;
})
})()
如果你愿意,你可以用for/while循环代替lodash。
检查https://blogs.msdn.microsoft.com/typescript/2015/11/03/what-about-asyncawait/
如果我没有正确理解或代码有问题,请让我知道,我会更新答案。
相关文章:
- 将其中一个异步方法重写为使用promise的方法
- Meteor:如何遍历一个数组,这是一个异步方法的结果
- 如何将异步方法返回的值发送到javascript中的另一个异步方法
- 在执行另一个异步函数之前,只有当条件为true时,才执行某些异步函数的最佳方法
- 等待上一个异步函数完成
- node.js:将一个异步函数列表应用于列表列表中的每一项
- 等待一个异步函数在Node.js中返回
- 另一个异步循环中的Javascript异步循环
- 如何在另一个异步`each`方法(NodeJS)内部进行异步方法调用
- 如何在nodejs中将参数从一个异步函数传递到另一个
- 为什么我不需要在Sails.js控制器函数中调用next,即使它在其主体中有一个(异步的?)数据库查询
- Javascript在另一个异步函数结束时调用函数
- 我如何知道最后一个异步函数何时在ob" for键中返回结果?循环
- 如何以组的方式调用一个异步函数?
- 确保两个函数一个接一个地执行,其中第一个函数内部有一个异步调用
- JS磁带-等待前一个异步测试完成,以移动到下一个测试
- 在javascript中使用for循环创建一个异步获取序列
- 如何用Meteor创建一个异步RESTful接口
- dispatchEvent是一个同步函数还是一个异步函数?
- 在Firebase节点客户端中,是一个异步函数