2 回答
TA贡献1798条经验 获得超3个赞
这是您要同时运行的代码。
//...
while (min < 1000) {
await scan(fruitID, min, min + 30);
min = min + 30;
}
//...
它目前正在同步运行。
有一个库抽象了限制并发操作的一些复杂性,它被称为promise-throttle。
该实现看起来类似于:
const promiseThrottle = new PromiseThrottle({
requestsPerSecond: 5, // up to 5 requests per second.. This will adjust the request rate
promiseImplementation: Promise, // the Promise library you are using
});
const scans = [];
// swapped while loop with for loop but it accomplishes effectively the same task
for (let i = 0; i < 1000; i += 30) {
// closure in order to get correct value of i on each iteration.
((min) => {
scans.push(promiseThrottle.add(() => scan(fruitId, min, min + 30)));
})(i);
}
Promise.all(scans).then(res => {
// res is an array of all responses from scans
// scans completed
});
promise-throttle在抽象节流方面做得非常好,但是 API 需要一秒钟才能习惯..
TA贡献1801条经验 获得超8个赞
这是一种使用高阶函数来包装现有函数的方法:
function throttle(max, fn) {
let queue = [];
let inProgress = new Set();
const runTaskNow = async (args) => {
inProgress.add(args);
await fn(...args);
inProgress.delete(args);
const next = queue.shift();
if (next) {
runTaskNow(next.args).then(next.resolve, next.reject);
}
};
const runTaskLater = args => {
let resolve, reject;
const promise = new Promise((yes, no) => {
resolve = yes;
reject = no;
});
queue.push({ resolve, reject, args });
return promise;
};
return (...args) => {
return inProgress.size < max ? runTaskNow(args) : runTaskLater(args);
}
}
要使用,请将您的函数包装为throttle:
const scan = throttle(5, (vFruitId, min, max) => {
return $.ajax({
// ...
});
});
...然后像您通常调用的那样调用它scan。
添加回答
举报