【问题标题】:How to use setTimeout in a for loop如何在 for 循环中使用 setTimeout
【发布时间】:2022-02-02 14:39:40
【问题描述】:

我正在discord.js 中构建一个 Minecraft 主题机器人,我写了一个命令,它基本上开始挖掘资源,然后等待一段时间,因为在现实生活中,在 Minecraft 中挖掘石头需要一些时间,它还取决于镐的类型。所以我想做的是,每次你挖出一个块后,它会根据你的镐的速度等待一段时间,然后再运行一次,为此,我想到了使用setTimeout() 函数。但是我遇到了一个问题。问题是,当setTimeout() 运行时,它并没有停在那里,而是继续执行setTimeout() 之后的代码,一旦setTimeout() 完成,它就会执行setTimeout() 中的代码。我已经研究了一段时间如何做到这一点,但它们似乎都不适用于我的想法。我的代码是这样的 =>

async execute(interaction) {
  // It gets the pickaxe details
  const pickaxe = require('../${pickaxeId}.js')
  // This gets the time to mine stone, coal and iron from the pickaxe file
  const timeToMineStone = pickaxe.stone
  const timeToMineCoal = pickaxe.coal
  const timeToMineIron = pickaxe.iron
  const minableBlocks = ['stone', 'coal', 'iron']
  var miningTime
  // It picks one block randomly from the minableBlocks and depending on it, it assigns a value to the miningTime variable
  // Code for picking the random block
  for (var mined = 0; mined <= 100; mined++) {
    setTimeout(() => {
      console.log('Time Out!')
    }, miningTime)
    // Rest of the code should only be executed after the setTimeout()
  }
}

但这里发生的情况是,在setTimeout() 之后编写的其余代码首先执行,然后在超时后,它会记录“超时!”到控制台。谁能帮我正确使用setTimeout()?任何帮助将不胜感激。

【问题讨论】:

  • 将“其余代码”移入setTimeout()回调函数
  • setTimeout() 是非阻塞的。它向系统注册计时器并立即返回并继续执行调用setTimeout() 之后的Javascript。我建议研究一下非阻塞到底是什么意思,因为它是 nodejs 中异步操作的一个重要概念。
  • @Phil,我尝试了您的建议并将所有代码移到了setTimeout() 回调函数中,但是现在一旦超时完成,一切都会立即运行!

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


【解决方案1】:

您的sleep 函数不起作用,因为setTimeout 没有(还没有?)返回一个可能是awaited 的承诺。您需要手动承诺:

function timeout(ms) {
    return new Promise(resolve => setTimeout(resolve, ms));
}
async function sleep(fn, ...args) {
    await timeout(3000);
    return fn(...args);
}

你的函数会变成

async function execute(interaction){
  // It gets the pickaxe details
  const pickaxe = require('../${pickaxeId}.js');
  // This gets the time to mine stone, coal and iron from the pickaxe file
  const timeToMineStone = pickaxe.stone
  const timeToMineCoal = pickaxe.coal
  const timeToMineIron = pickaxe.iron
  const minableBlocks = ['stone', 'coal', 'iron']
  var miningTime
  // It picks one block randomly from the minableBlocks and depending on it, it assigns a value to the miningTime variable
  // Code for picking the random block
  for (var mined = 0; mined <= 100; mined++) {
    timeout( () => {
      console.log('Time Out!')
    }, miningTime)
    // Rest of the code should only be executed after the setTimeout()
  }
}

here 提出了类似的问题。 复制自this answer。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-05-02
    • 2015-04-26
    • 1970-01-01
    • 2019-10-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-08-21
    相关资源
    最近更新 更多