For循环中的setTimeout不起作用

setTimeout in For loop not working

在我的 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();
}

问题是 doSetTimeout() 被同步调用 times 次。所以假设 for 循环需要 5 毫秒才能完成,您预计第一个 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);
}

setTimeout - 不等待 - 它 returns 立即超时处理程序,所以你 运行 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)

您需要根据循环更新延迟,换句话说,您需要使其成为 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();
}