gpt4 book ai didi

javascript - Angular 2 中用于双向数据绑定(bind)的共享 RxJS 主题

转载 作者:太空狗 更新时间:2023-10-29 17:48:42 26 4
gpt4 key购买 nike

我有一个用于应用程序设置的单例服务

class Setting {
get foo() {
return storage.get('foo');
}

set foo(val)
storage.set('foo', val);
}
}

在组件的 View 中绑定(bind)为 setting.foo

因为 storage 调用可能代价高昂并且可能是异步的,所以我更愿意用 RxJS 主题替换 getter/setter,以便在需要时更新和读取 storage

所以我将其重构为

class Setting {

constructor() {
this.fooSubject = new ReplaySubject(1);

fooSubject.subscribe((val) => {
storage.set('foo', val);
});

this.foo$ = this.fooSubject
.map(() => storage.get('foo'))
.publishReplay(1).refCount();
}

并像 setting.foo$ | 一样使用它异步setting.fooSubject.next(newFoo)。看起来代价高昂的 storage.get 调用现在已被缓存。

有两个问题。

第一个是 fooSubject subject 和 foo$ observable 都应该是公开可用的才能使这项工作有效,而选择 subject 是因为它应该是两者一个可观察对象和一个观察者。

能否将 foo$ 设为 Setting 服务的单个 Subject 属性,以便使用 subscribe(...) 进行订阅> 并更新为 next(...)?

第二个是代码仍然是同步的。

对于返回 promise 的 storage.getstorage.set 如何处理这种情况?

最佳答案

当您的代码真正按照您的意愿工作时,您的代码中没有太多建议。我不确定我是否完全理解您的用例,但我认为您可以通过完全不使用 this.foo$ 来简化您的代码。

存储最新值的功能由ReplaySubject提供除非你真的需要每次在 storage.set('foo', val); 之后调用 storage.get('foo'),否则没有必要。

我将您的代码放入现场演示中:http://plnkr.co/edit/pxjRQr6Q6Q7LzYb1oode?p=preview

所以我觉得可以简化成这样。

class Setting {

constructor() {
var storage = new Storage();

this.fooSubject = new ReplaySubject(1);
this.fooSubject.subscribe((val) => {
storage.set('foo', val);
});
}

get observable() {
return this.fooSubject.asObservable();
};

store(val) {
this.fooSubject.next(val);
}
}

我故意隐藏了一个事实,即我正在使用一个带有 .asObservable()Subject并通过使用 store() 方法包装 .next() 调用。典型用法如下:

let settings = new Setting();

settings.store('Hello');

settings.observable.subscribe(val => console.log(val));
settings.store('Hello 2');
settings.store('Hello 3');

settings.observable.subscribe(val => console.log(val));
settings.store('Hello 4');

打印到控制台:

Hello
Hello 2
Hello 3
Hello 3
Hello 4
Hello 4

请注意,您没有使用任何值初始化 ReplaySubject。即使您在创建 ReplaySubject 后立即调用了 setting.fooSubject.next(newFoo),它也会在使用 storage.set('foo) 订阅后立即再次存储', val);.

关于同步的问题。好吧,您的代码实际上是异步但顺序的。由于 JavaScript 是单线程的,因此如果 storage.get('foo') 执行一些同步耗时操作,那么它将阻塞执行线程,可能唯一的选择是将其移至 Web Worker。

关于javascript - Angular 2 中用于双向数据绑定(bind)的共享 RxJS 主题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39781235/

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