gpt4 book ai didi

javascript - 如何透明地将原生 JavaScript 变量转换为响应式 Meteor 变量?

转载 作者:行者123 更新时间:2023-11-29 10:11:49 25 4
gpt4 key购买 nike

当 native 变量更改时,不会重新运行跟踪器计算:

var foo = 'foo';
Tracker.autorun(function logFoo() { console.log('foo is:', foo); });

这段代码只会执行一次:

foo is:
'foo'

计算没有依赖性,没有_onInvalidateCallback。它几乎死了。

然而,在很多情况下,我确实需要一个本地 JavaScript 变量或对象字段以某种方式在 Tracker 计算中响应式(Reactive)运行(本地 API 未完全移植到 Meteor,...)

当然不能简单的写:

foo = new ReactiveVar(foo);

因为我会破坏当前帧的引用,而其他函数可能会使用 foo 的另一个引用,从而导致不同步和痛苦和头痛。
以类似的方式...

obj.foo = new ReactiveVar(obj.foo);

这也会中断,因为 obj.foo 现在完全不同并且依赖于 obj.foo 的代码是一个简单的非 react 性值将立即中断。< br/>它对模块模式(对 obj.foo 的孤立引用)也没有用,并且会导致更多的去同步化和更多的痛苦,甚至更多的头痛。

如何在不破坏遗留代码的情况下将原生 Javascript 变量或对象字段正确更改为 Reactive-Var?

最佳答案

本地变量和对象字段这两种情况需要分开处理,它们需要不同的方法。第一个将使用简单但肮脏的技巧,第二个将使用更高级的技巧。
让我们从 native 变量大小写开始。


对象字段

如果变量是可写对象字段,那么我们可以将引用更改为make a custom get/set couple链接到闭包中的 react 变量。
就这么简单:

function reactivise(obj, field) {
var rvar = new ReactiveVar(obj[field]);

Object.defineProperty(obj, field, {
get : function() {
return rvar.get();
},
set : function(value) {
rvar.set(value);
return value;
}
})
}

而且效果很好。使用 obj.foo 的 native 代码不会注意到更改(除非他们检查属性描述符,但这是一件很奇怪的事情)。然而,响应式计算将因更改此字段而失效。
但是,它对模块模式(防止损坏的引用隔离)很弱。这是此类模块的示例:

(function logFoo(foo) {
console.log(foo);
}(obj.foo);

此代码不会关心您是否更改了 getter 或 setter,它已经包含引用。

可能有解决此问题的方法...但在撰写本文时,它几乎是炼金术。一个可以提供帮助的 ES7 特性:Object.observe .今天太年轻了,我就不举例了。


变量

如果你想观察的不是非模块化对象字段(上面的例子),那么我所知道的唯一解决方案是轮询。
基本上,定期检查值是否更改,并为此设置一个 react 变量(我们失去了透明度)。

这种轮询的例子:

function reactivePoll(getter) {
var rPoll = new ReactiveVar(getter());

Meteor.setInterval(function pollVariable() {
var newValue = getter();
if(!_.isEqual(rPoll.curValue, newValue)) {
rPoll.set(newValue);
}
}, 100);

return rPoll;
}

我们需要它工作的不是变量引用本身 (foo),而是这个变量的 getter。这是因为如果稍后在代码中更改了 foo 引用,我们的函数将不会意识到它(仍然是更痛苦的去同步头痛)。
另外,我们每次都必须检查深度相等性,以确保在我们导致失效之前值确实发生了变化,因为如果 Tracker 看到非原始值,它会自动失效。

使用示例:

var reactiveFoo = reactivePoll(function getFoo() { return foo; });

它当然也适用于对象字段。
请注意,示例代码没有任何类型的停止机制。它会永远运行,可能会引发内存泄漏、崩溃、减慢您的应用程序并导致剧烈的头痛。不要在生产应用程序中使用它,调整它以更好地控制间隔。


最安全的选择是基本的脏轮询,即使这意味着需要更多的负载和完整的控制来防止内存泄漏。

关于javascript - 如何透明地将原生 JavaScript 变量转换为响应式 Meteor 变量?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31972888/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com