以下 TypeScript 一次执行对 doSomething(action)
的每次调用。 (这意味着列表中的第二项在第一项完成之前不会被调用)。
async performActionsOneAtATime() {
for (let action of listOfActions) {
const actionResult = await doSomethingOnServer(action);
console.log(`Action Done: ${actionResult}`);
}
}
这将立即向服务器发送所有请求(无需等待任何响应):
async performActionsInParallel() {
for (let action of listOfActions) {
const actionResultPromise = doSomething(action);
actionResultPromise.then((actionResult) => {
console.log(`Action Done: ${actionResult}`);
});
}
}
但我真正需要的是一种抑制它们的方法。一次可能有 10 或 20 个调用打开。 (一次一个太慢了,但是全部 600 个会使服务器过载。)
但我很难弄明白这一点。
关于如何限制一次打开 X 的调用次数有什么建议吗?
(这个问题使用 TypeScript,但我可以使用 ES6 JavaScript 回答。)
最佳答案
您可以在一个简短的函数中完成此操作。 (根据 naomik 的建议按顺序返回值。谢谢!)
/**
* 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;
}).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(() => {
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));
关于javascript - 限制在给定时间打开的 promise 数量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38385419/