防止JS/TS中的设置器上的无限循环

发布于 2025-01-20 19:33:07 字数 613 浏览 0 评论 0原文

使用 TypeScript,我一直在尝试设置我所说的“触发器”:一个包含 checker 函数(返回布尔值)和 behavior 函数的对象,它基本上可以做任何事情。 我想要做的是每次更改某个变量的值时,都会执行触发器的 checker 函数,如果返回 true,则也会运行 behavior 函数。

当然,我将触发器的 checker 函数调用放在 setter 中:

set health(value: number) {
    this._health = value;
    runTriggers();
}

触发器的行为函数的目标是执行任何操作,但主要是更改变量的值强>。 这就是问题所在:如果像上面那样在 health setter 中调用触发器,并且触发器的行为函数也会更改 health 变量(从而调用setter 再次),它将以无限递归调用结束。

如何防止这种无限调用的发生,同时仍然允许触发器的行为函数自由更改变量?

With TypeScript, I've been trying to set up what I call a "trigger" : an object that contains a checker function (returns a Boolean) and a behavior function, which can do basically anything.
What I want to do is every time a certain variable's value is changed, the checker function of the trigger is executed, and if it returns true, the behavior function is ran too.

Naturally, I put the trigger's checker function call in a setter :

set health(value: number) {
    this._health = value;
    runTriggers();
}

The goal of a trigger's behavior function is to do anything, but mainly change values from variables.
And that is where the problem is : if a trigger is called in the health setter like above, and the behavior function of the trigger also changes the health variable (thus calling the setter again), it will end up in an infinite recursive call.

How could I prevent this infinite call from happening, while still allowing my trigger's behavior function to freely change variables?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

别忘他 2025-01-27 19:33:07

该解决方案可能非常取决于您的总体设计选择。从根本上讲,您必须有一种方法来说“不要做无限的循环”,这意味着某个地方的某个地方必须能够设置health /em>运行触发器。

一个简单的标志可以让您避免一个递归触发呼叫:

set health(value: number) {
    this._health = value;
    if (!this._healthTriggerActive) {
        this._healthTriggerActive = true;
        try {
            runTriggers();
        } finally {
            this._healthTriggerActive = false;
        }
    }
}

...但是,这当然意味着在触发回调中设置health都不会运行触发器(因为这是基本问题)。

您也可以使用计数器限制深度,从而允许一定量的递归,但不要太多;但这可能只是隐藏了问题。

The solution is likely to be very dependent on your overall design choices. Fundamentally, you have to have a way to say "don't do an infinite loop," which means that somewhere, sometime, something is going to have to be able to set health without running triggers.

A simple flag would let you avoid even one recursive trigger call:

set health(value: number) {
    this._health = value;
    if (!this._healthTriggerActive) {
        this._healthTriggerActive = true;
        try {
            runTriggers();
        } finally {
            this._healthTriggerActive = false;
        }
    }
}

...but that of course means that setting health in a trigger callback won't run triggers (since that's the basic problem).

You could also limit depth with a counter, allowing a certain amount of recursion but not too much; but that's probably just hiding the problem.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文