在特定时间打开承诺的承诺金额 [英] Throttle amount of promises open at a given time
问题描述
以下Typescript每次执行一次对 doSomething(action)
的每次调用。 (意思是列表中的第二项在第一项完成之前不会进行调用)。
The following Typescript performs each call to doSomething(action)
one at a time. (Meaning the second item in the list does not get a call made until the first one is done).
async performActionsOneAtATime() {
for (let action of listOfActions) {
const actionResult = await doSomethingOnServer(action);
console.log(`Action Done: ${actionResult}`);
}
}
这个会将所有请求发送到服务器权利离开(不等待任何回复):
This one will send all the requests to the server right away (without waiting for any responses):
async performActionsInParallel() {
for (let action of listOfActions) {
const actionResultPromise = doSomething(action);
actionResultPromise.then((actionResult) => {
console.log(`Action Done: ${actionResult}`);
});
}
}
但我真正需要的是一种方法来扼杀他们。也许一次打开10或20个电话。 (一次一个太慢,但所有600都会使服务器超载。)
But what I really need is a way to throttle them. Maybe have 10 or 20 calls open at a time. (One at at a time is too slow, but all 600 will overload the server.)
但我很难搞清楚这一点。
But I am having a hard time figuring this out.
有关如何限制每次打开X的来电数量的任何建议吗?
(这个问题使用TypeScript,但我对ES6 JavaScript答案没问题。)
(This question uses TypeScript, but I would be fine with an ES6 JavaScript answer.)
推荐答案
你可以在一个简短的功能中执行此操作(更新:按照naomik的建议按顺序返回值。)
You can do this in one short function. (Update: Returns values in order per naomik's suggestion.)
/**
* Performs a list of callable actions (promise factories) so that only a limited
* number of promises are pending at any given time.
*
* @param listOfCallableActions An array of callable functions, which should
* return promises.
* @param limit The maximum number of promises to have pending at once.
* @returns A Promise that resolves to the full list of values when everything is done.
*/
function throttleActions(listOfCallableActions, limit) {
// We'll need to store which is the next promise in the list.
let i = 0;
let resultArray = new Array(listOfCallableActions.length);
// Now define what happens when any of the actions completes. Javascript is
// (mostly) single-threaded, so only one completion handler will call at a
// given time. Because we return doNextAction, the Promise chain continues as
// long as there's an action left in the list.
function doNextAction() {
if (i < listOfCallableActions.length) {
// Save the current value of i, so we can put the result in the right place
let actionIndex = i++;
let nextAction = listOfCallableActions[actionIndex];
return Promise.resolve(nextAction())
.then(result => { // Save results to the correct array index.
resultArray[actionIndex] = result;
return;
}).then(doNextAction);
}
}
// Now start up the original <limit> number of promises.
// i advances in calls to doNextAction.
let listOfPromises = [];
while (i < limit && i < listOfCallableActions.length) {
listOfPromises.push(doNextAction());
}
return Promise.all(listOfPromises).then(() => resultArray);
}
// Test harness:
function delay(name, ms) {
return new Promise((resolve, reject) => setTimeout(function() {
console.log(name);
resolve(name);
}, ms));
}
var ps = [];
for (let i = 0; i < 10; i++) {
ps.push(() => delay("promise " + i, Math.random() * 3000));
}
throttleActions(ps, 3).then(result => console.log(result));
这篇关于在特定时间打开承诺的承诺金额的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!