【问题标题】:When creating a function to run only one time, should the redefinition happen before or after the function?当创建一个只运行一次的函数时,重新定义应该发生在函数之前还是之后?
【发布时间】:2017-12-30 20:02:42
【问题描述】:

我希望一个函数只运行一次。我在 SO 上找到了this question,投票率最高的示例重新定义了函数,然后执行应该运行一次的代码。我确信这样做是有充分理由的,而不是运行代码然后重新定义函数,但我不知道那会是什么。我的第一直觉是只在代码运行后重新定义函数,因为这看起来“更安全”,因为代码必须在重新定义之前运行。

有人能解释一下为什么约定似乎首先要重新定义吗?

【问题讨论】:

  • 请在您的问题中添加相关语言标签。
  • 如果你在谈论javascript那么没有区别,因为没有线程 - 只有一个事件循环,你的函数不能同时从多个线程调用,但只能依次。阅读更多关于 js 中的事件循环developer.mozilla.org/en-US/docs/Web/JavaScript/EventLoop
  • 所以是为了防止它在多线程环境中多次运行。说得通!是的,我正在使用 JavaScript,但我认为这是一个普遍的问题,所以我把它留了下来。由于它的广泛使用,我添加了 JS 标签,即使这个问题适用的范围更广。感谢您的回复。

标签: javascript function design-patterns


【解决方案1】:

基本上,如果您想避免函数被“调用”两次,那么在第一次调用后立即禁用该函数是最安全的做法。当调用和禁用程序之间没有其他事情发生时,也不会发生任何意外。如果您要运行应该首先执行一次的代码,可能会发生各种事情:

  • 代码递归调用函数,或者通过回调 - 你应该考虑reentrancy
  • 代码确实引发了异常
  • 代码returns 早

在任何这些情况下,甚至更多情况下,都无法达到禁用代码,并且可以进行第二次调用。

还要注意,仅替换函数是不够的。调用者可以很容易地创建一个别名变量,该变量仍然保存原始函数,不受将其他变量设置为 noop 函数的影响。您始终需要将此解决方案与accepted answer 中的“静态布尔变量”方法结合使用,除非您控制调用代码并知道它的作用。

【讨论】:

    【解决方案2】:

    看起来主要原因是多线程语言。如果一个函数应该只运行一次,并且在第一个实例完成之前被第二次调用,那将导致被多次调用。先重新定义,意味着函数不能运行两次。

    【讨论】:

    • JS 不是多线程的。同样在多线程语言中,尽快禁用可能会减少竞争条件的机会,但要获得适当的解决方案,就需要信号量或原子操作。
    • 我没说JS是多线程的。正如对原始问题的评论中所述,对于 JS,顺序无关紧要。我正在回答我自己的问题,以便其他任何人发现这个问题都会有理由说明为什么要首先重新定义函数。
    猜你喜欢
    • 2021-05-29
    • 1970-01-01
    • 1970-01-01
    • 2018-05-10
    • 2015-09-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多