在同一时刻多次调用函数,但在nodejs中延迟执行不同的调用

我需要从不同的上下文中多次调用一个函数,但是我需要每次调用都不会在上一次调用之后经过一秒之后触发。

我会举一个例子:

var i = 0; while(i<50) { do_something(i) i++ } function do_something(a) { console.log(a) } 

我想要这个日志:'1',然后在第二个'2',然后在第二个'3'之后,然后在第二个'4'之后…

我不能使用简单的setInterval或setTimeout,因为这个函数“do_something(param)”可以在不同的来源在同一时间被调用,因为我正在与nodejs中的asynchronousfunction。 我希望保持通话的顺序,但是他们以最less的延迟一秒钟发射。

我想我应该将这些调用添加到一个队列,然后每秒一个调用出队和函数触发,但我真的不知道如何在nodejs中做到这一点。 先谢谢你

我不得不这样做:

 var tasks = [] //global var var processor = setInterval(function() { process_task()}, 1000) function add_task() { tasks.push('my task') //add task to the end of queue } process_task() { var task_to_use = tasks[0]; tasks.shift() //remove first task in the queue (tasks[0]) //do what i need to with the task 'task_to_use' } 

通过这种方式,我可以将任务添加到队列中( tasks是全局上下文的variables),只是调用tasks.push('mytask') ,任务将按照它们的顺序每秒处理一个队列。

但是,我真的不需要这样做。 我需要,因为我正在使用Twilio的apis,并在他们的文档中,我读了每个电话号码可以发送到短信第二,但没有更多,但支持告诉我,他们排队请求,每秒发送一条消息,以便发送更多比第二个请求是真的不是一个问题,没有短信发送将失败。 希望这会有所帮助,byee

晚会到晚会

我知道我迟到了,但是我对这个完全相同的技术也有同样的问题。

您的post非常有帮助,但缺乏良好的做法并使用全局variables。

我的解决scheme

如果你今天正在读这本书,我想让你知道,在一个星期的抨击我的头后,我最终创造了一个问题,导致两个不同的答案,都能够帮助你:

  • 如何延迟JavaScript的function执行

由@ Arg0n开创并由我改编的队列方法与您的例子最为接近,但是您没有任何缺点:

 let asyncFunc = function(url) { return new Promise((resolve, reject) => { setTimeout(function() { resolve({ url: url, data: "banana" }); }, 5000); }); }; let delayFactory = function(args) { let { delayMs } = args; let queuedCalls = []; let executing = false; let queueCall = function(url) { return new Promise((resolve, reject) => { queuedCalls.push({ url, resolve, reject }); if (executing === false) { executing = true; nextCall(); } }); }; let execute = function(call) { console.log(`sending request ${call.url}`); asyncFunc(call.url) .then(call.resolve) .catch(call.reject); setTimeout(nextCall, delayMs); }; let nextCall = function() { if (queuedCalls.length > 0) execute(queuedCalls.shift()); else executing = false; }; return Object.freeze({ queueCall }); }; let myFactory = delayFactory({ delayMs: 1000 }); myFactory.queueCall("http://test1") .then(console.log) .catch(console.log); myFactory.queueCall("http://test2") .then(console.log) .catch(console.log); myFactory.queueCall("http://test3") .then(console.log) .catch(console.log);