For循环中的setTimeout不起作用

时间:2017-06-26 22:38:36

标签: javascript node.js for-loop settimeout discord

在我的Discord.js机器人中,我正在尝试创建一个垃圾邮件命令,每隔3/4秒(750毫秒)发送一条消息。但是,它会在发送第一条消息之前等待3/4秒,但会停止等待其余的消息;从字面上吐出疯狂的消息。我怎样才能解决这个问题? https://pastebin.com/qdTV2Hre

function doSetTimeout(){
    setTimeout(function(){
        message.channel.send(msg);
    }, 750);
}
for (i = 0; i < times; i++) {
    message.channel.startTyping();
    doSetTimeout();
    message.channel.stopTyping();
}

3 个答案:

答案 0 :(得分:1)

您需要根据循环更新延迟,换句话说,您需要使其成为i的倍数,因此每次迭代都会在前一次迭代之后出现。

function doSetTimeout(delay){
    setTimeout(function(){
        message.channel.send(msg);
    }, (delay+1)*750);
}
for (i = 0; i < times; i++) {
    message.channel.startTyping();
    doSetTimeout(i);
    message.channel.stopTyping();
}

示例演示:

function doSetTimeout(delay){
    setTimeout(function(){
        //message.channel.send(msg);
        console.log('Message '+delay);
    }, (delay+1)*750);
}
for (i = 0; i < 10; i++) {
    //message.channel.startTyping();
    doSetTimeout(i);
    //message.channel.stopTyping();
}

答案 1 :(得分:0)

问题是doSetTimeout()被同步调用times次。因此,假设for循环需要5ms才能完成,您希望第一个setTimeout需要750毫秒,但其余的将在5毫秒内完成。

有两种可能的解决方案:

1)从它自己的回调中启动setTimeout。现在,每个并发setTimeout只会在完成上一个时启动:

var count = 0

function doSetTimeout(){
  if (count < times) {
    setTimeout(function(){
      count++;
      message.channel.send(msg);
      doSetTimeout();
    }, 750);
  }
}

2)您也可以使用与setInterval类似的方法:

var count = 0
var timer

function doSetTimeout(){
  timer = setInterval(function(){
    if (count < times) {
      count++;
      message.channel.send(msg);
    } else {
      clearInterval(timer)
    }
  }, 750);
}

答案 2 :(得分:0)

setTimeout - 没有等待 - 它会立即返回超时处理程序,因此您运行10次startTyping() ... stopTyping(),而不是750次10次send(msg)

如果您想在消息之间等待750毫秒,可以尝试以下操作:

function writeSomething(n) {
  if(n>0) {
    setTimeout(function(){
        message.channel.startTyping();
        message.channel.send(msg);
        message.channel.stopTyping();
        writeSomething(n-1)
    }, 750);
  }
}

writeSomething(10)