为了账号安全,请及时绑定邮箱和手机立即绑定

如何同时运行一个函数的 3 个实例

如何同时运行一个函数的 3 个实例

DIEA 2022-07-15 10:01:51
我有一个名为scan(). 它被循环调用。但是,它当前的工作方式:来电scan()等待scan()归来增加min重复我怎样才能使它同时运行2实例scan()。我可以在哪里将2实例更改为3实例4或5等。示例:我希望它如何(在下面的示例中,有在任何一个时间点运行的3实例scan()。它不应该有超过3扫描运行的实例(关于 while 循环条件)。在后台调用scan()并等待返回值。一旦它获得返回值,它就会增加min并调用scan(). 总是3有运行的实例scan()(关于 while 循环条件)<script type="text/javascript" src="https://code.jquery.com/jquery-1.9.1.min.js"></script><div class="display-error" style="display: none"></div><form>  <label for="fname">Fruit (only correct input is: banana)</label><br>  <input type="text" id="fruit-name" name="fruit" value="banana"><br>  <button type="submit" id="submit" value="Submit">Submit</button></form><div id="results"></div><script type="text/javascript">$(document).ready(function() {    $('#submit').click(function(e) {        e.preventDefault();        var fruitName = $("#fruit-name").val();        $.ajax({            type: "POST",            url: "verify-input.php",            dataType: "json",            data: {                fruitName: fruitName            },            success: function(data) {                if (data.code == 200) {                    $("#submit").html("Running Scan");                    (async function() {                        var fruitID = data.fruitId;                        var min = 1;                        while (min < 1000) {                            await scan(fruitID, min, min + 30);                            min = min + 30;                        }                    })();                } else {                    $(".display-error").html("<ul>" + data.msg + "</ul>");                    $(".display-error").css("display", "block");                }            }        });    });});function scan(vFruitId, min, max) {    return $.ajax({        type: "POST",        url: "scanner.php",        dataType: "json",        data: {            vFruitId: vFruitId,            min: min,            max: max        },
查看完整描述

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 需要一秒钟才能习惯..


查看完整回答
反对 回复 2022-07-15
?
蝴蝶刀刀

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。


查看完整回答
反对 回复 2022-07-15
  • 2 回答
  • 0 关注
  • 92 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信