【问题标题】:Exiting a callback function that is called within a loop退出在循环中调用的回调函数
【发布时间】:2018-10-20 04:51:39
【问题描述】:

为了好玩,我编写了这个小辅助函数,以使循环更易于阅读。它基本上包装了一个while循环并将回调作为参数。现在,我发现自己想知道如何从回调函数中跳出 while 循环。简单地从回调中返回是行不通的,我也不能从回调中调用 break。

const loopFor = (time) => {
  return {
    milliseconds: (callback) => {
      const start = Date.now()
      while (Date.now() - start < time) {
        callback()
      }
    }
  }
}

loopFor(100).milliseconds(() => {
  console.log("Weeeeeeee, I'm looping")
})
console.log("Done looping")

【问题讨论】:

  • 你不能 - JS 中的用户空间是单线程的。
  • 循环喜欢这些是一个非常糟糕的主意,请考虑使用setIntervalsetTimeout
  • 除非你想在你的回调中有某种返回值并检查你是否调用break,否则你不能这样做。尽管如此,正如@Keith 所说,这个循环首先是一个坏主意。如果您在浏览器中运行它,它将在循环期间阻止您页面上的 所有 JavaScript 执行。
  • 要扩展@Keith 的评论,这很糟糕,因为它会阻塞事件循环并且其他事情没有机会运行。这对 Node 来说并不是 不好,但你绝对应该在前端代码中避免这种情况。
  • 谢谢大家,我知道它阻塞了线程。我主要在 Node 中使用它,用于运行 Monte Carlo Tree Search 之类的东西,您希望在给定时间内运行算法。在浏览器中,我使用 WebWorkers 让它在不同的线程中运行。

标签: javascript loops while-loop callback break


【解决方案1】:

我不认为这是一个可取的方法,但如果你必须继续使用这种方法,你将不得不围绕提供一些返回值来设计你的回调来打破 while 循环。

例如

const loopFor = (time) => {
  return {
    milliseconds: (callback) => {
      const start = Date.now()
      while (Date.now() - start < time) {
        if (!callback()){ //Break if callback returns false
          break;
        }
      }
    }
  }
}

loopFor(100).milliseconds(() => {
  console.log("Weeeeeeee, I'm looping")
  let condition = 1 > 5 //Some abritrary condition
  return condition
})
console.log("Done looping")

【讨论】:

    【解决方案2】:

    你可以从回调中返回

    const loopFor = (time) => {
      return {
        milliseconds: (callback) => {
          const start = Date.now()
          while (Date.now() - start < time && callback());
        }
      }
    }
    
    let counter = 5;
    loopFor(100).milliseconds(() => {
      console.log("Weeeeeeee, I'm looping")
      if(--counter==0)return false
      return true
    })
    console.log("Done looping")

    或者你可以抛出异常

    class LoopEnd{}
    const loopFor = (time) => {
      return {
        milliseconds: (callback) => {
          const start = Date.now()
          try{while (Date.now() - start < time)callback();}
          catch(e){if(!(e instanceof LoopEnd))throw e;}
        }
      }
    }
    
    let counter = 5;
    loopFor(100).milliseconds(() => {
      console.log("Weeeeeeee, I'm looping")
      if(--counter==0)throw new LoopEnd()
    })
    console.log("Done looping")

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-01-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-04-05
      相关资源
      最近更新 更多