Javascript 如何同时运行一个函数的3个实例
我有一个名为Javascript 如何同时运行一个函数的3个实例,javascript,html,jquery,while-loop,async-await,Javascript,Html,Jquery,While Loop,Async Await,我有一个名为scan()的函数。它在循环中被调用。但是,它当前的工作原理是: 调用scan() 等待scan()返回 增加min 重复 如何使其同时运行scan()的2实例。我可以将2实例更改为3实例或4或5等 示例:我希望它是什么样子(在下面的示例中,scan()的3个实例在任何一个时间点运行。它运行的扫描实例不应超过3个(相对于while循环条件) 调用scan()并在后台等待返回值。一旦获得返回值,它将增加min,并调用scan()的另一个实例。始终有scan()实例在运行(与while循
scan()
的函数。它在循环中被调用。但是,它当前的工作原理是:
scan()
scan()
返回min
scan()
的2
实例。我可以将2
实例更改为3
实例或4
或5
等
示例:我希望它是什么样子(在下面的示例中,scan()
的3个实例在任何一个时间点运行。它运行的扫描实例不应超过3个(相对于while循环条件)
调用scan()
并在后台等待返回值。一旦获得返回值,它将增加min
,并调用scan()
的另一个实例。始终有scan()
实例在运行(与while循环条件有关)
水果(唯一正确的输入是:香蕉)
提交
$(文档).ready(函数(){
$(“#提交”)。单击(函数(e){
e、 预防默认值();
var fruitName=$(“#fruit name”).val();
$.ajax({
类型:“POST”,
url:“验证输入.php”,
数据类型:“json”,
数据:{
果名:果名
},
成功:功能(数据){
如果(data.code==200){
$(“#提交”).html(“运行扫描”);
(异步函数(){
var FROUTID=data.FROUTID;
var min=1;
而(最小值<1000){
等待扫描(水果ID,最小值,最小值+30);
最小值=最小值+30;
}
})();
}否则{
$(“.display error”).html(“”+data.msg+”
”);
$(“.display error”).css(“display”、“block”);
}
}
});
});
});
功能扫描(vFruitId、最小值、最大值){
返回$.ajax({
类型:“POST”,
url:“scanner.php”,
数据类型:“json”,
数据:{
vFruitId:vFruitId,
敏:敏,,
马克斯:马克斯
},
成功:功能(数据){
data.forEach((项目,idx)=>{
$(“#结果”)。追加(`
卡路里:${item.sweetness}
甜度:${item.carries}
苦味:${item.sarress}
`);
})
}
});
}
这是您希望同时运行的代码
/。。。
而(最小值<1000){
等待扫描(水果ID,最小值,最小值+30);
最小值=最小值+30;
}
//...
目前它正在同步运行
有一个库,它抽象了限制并发操作的一些复杂性,称为
实施过程大致如下:
const promisetrottle=新的promisetrottle({
requestsPerSecond:5,//每秒最多5个请求。这将调整请求速率
promiseImplementation:Promise,//您正在使用的Promise库
});
常量扫描=[];
//将while循环与for循环交换,但它可以有效地完成相同的任务
对于(设i=0;i<1000;i+=30){
//闭包,以便在每次迭代中获得正确的i值。
((最小)=>{
scans.push(promisetrottle.add(()=>scan(水果ID,min,min+30));
})(i) );
}
承诺。所有(扫描)。然后(res=>{
//res是扫描的所有响应的数组
//扫描完成
});
抽象节流功能做得很好,但API需要一秒钟才能习惯..下面是一种使用高阶函数包装现有函数的方法:
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);
}
}
…然后像通常调用scan
一样调用它,这是因为scan函数不返回任何promises@MisterJojo,$。ajax
确实返回了一个承诺。问题是这些请求是同步运行的,而不是并发运行的。那么我实际上应该如何使用它呢?就像while循环部分一样?您能给我演示一下我的while lo吗op part?我也不明白scan()
函数应该是什么样子。
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);
}
}
const scan = throttle(5, (vFruitId, min, max) => {
return $.ajax({
// ...
});
});