【问题标题】:Call function multiple times in the same moment but execute different calls with delay in nodejs在同一时刻多次调用函数,但在nodejs中延迟执行不同的调用
【发布时间】:2014-09-26 09:13:42
【问题描述】:

我需要从不同的上下文多次调用一个函数,但我需要在上一次调用开始后的一秒之前触发每个调用。

我举个例子:

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 中的异步函数。 我希望保持调用的顺序,但它们会以一秒的最小延迟触发。

我想我应该将这些调用添加到一个队列中,然后每一秒都会有一个调用出列并且函数会触发,但我真的不知道如何在 nodejs 中执行此操作。提前谢谢你

【问题讨论】:

  • “异步”第 3 方模块有一个很好的队列实现作为其中的一部分。
  • 为什么不能使用setInterval() 仍然没有任何意义。这正是它的用途。
  • 嗨 Morrisda,您需要了解 NodeJS 中的闭包。请阅读howtonode.org/why-use-closure。那里有一些很好的例子,说明您尝试使用 setTimeout 尝试什么
  • 解决了我的问题,谢谢大家
  • @Morrisda - 如果您自己解决了问题,那么您应该发布自己问题的答案(然后您可以接受)或删除您的问题,以便结束本主题。

标签: javascript node.js events queue timing


【解决方案1】:

我不得不这样做:

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 是全局上下文的变量),只需调用 tasks.push('mytask') 并且任务将按照它们放入的顺序每秒处理一个队列。

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

【讨论】:

    【解决方案2】:

    聚会迟到

    我知道我迟到了,但我在使用完全相同的技术时遇到了完全相同的问题。

    您的帖子很有帮助,但它缺乏良好的做法并使用了全局变量。

    我的解决方案

    如果您今天阅读本文,我想让您知道,经过一周的抨击后,我最终创建了一个问题,导致两个不同的答案,都能够帮助您:

    由@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);

    试一试,玩得开心!

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2023-01-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-15
      • 2021-08-19
      相关资源
      最近更新 更多