Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/406.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 在flatMapLatest中重新使用订阅_Javascript_Rxjs - Fatal编程技术网

Javascript 在flatMapLatest中重新使用订阅

Javascript 在flatMapLatest中重新使用订阅,javascript,rxjs,Javascript,Rxjs,我有以下RxJS定义: onIds .flatMapLatest((ids) => Rx.Observable .from(ids) .flatMap((id) => onUpdated(id))) 这很有效。但是,onUpdated是一个昂贵的重新启动订阅(即它有一个套接字连接)。因此,如果有一种方法可以重用以前ids实例中的订阅,那么我更愿意这样做,但是我不确定如何以实用的方式实现这一点 编辑: 我能想出的最好办法是: function cach

我有以下RxJS定义:

onIds
    .flatMapLatest((ids) => Rx.Observable
      .from(ids)
      .flatMap((id) => onUpdated(id)))
这很有效。但是,
onUpdated
是一个昂贵的重新启动订阅(即它有一个套接字连接)。因此,如果有一种方法可以重用以前
ids
实例中的订阅,那么我更愿意这样做,但是我不确定如何以实用的方式实现这一点

编辑:

我能想出的最好办法是:

function cached(factory) {
  return (id) => {
    const cache = factory._cached_cache || (factory._cached_cache = new Map())
    const x = cache.get(id)
    return x ? x : Rx.Observable.defer(() => {
        const x = factory(id)
          .finally(() => cache.delete(id))
          .share()
        cache.set(id, x)
        return x
      })
    }
}

onIds
    .flatMapLatest((ids) => Rx.Observable
      .from(ids)
      .flatMap(cached(onUpdatedCache))

发布更多关于更新的
的信息会有所帮助。在不了解更多信息的情况下,我认为解决方案最有可能使用一些依赖项注入技术将实时套接字连接作为参数传递给
onUpdated
,而不是让该方法创建自己的方法

或者

Rx.Observable.using(
    () => new SocketConnection(...),
    socket => onIds.flatMapLatest(ids => Observable
        .from(ids)
        .flatMap(id => onUpdated(socket, id))));
或者用一些封装

Rx.Observable.using(
    () => new Updater(...),
    updater => onIds.flatMapLatest(ids => Observable
        .from(ids)
        .flatMap(id => updater.onUpdated(id))));
编辑:

根据您最新的描述,除了您的记忆技巧之外,我能想到的唯一方法是对
id
数组中
id
的实际进出进行建模。大概是这样的:

onIds
    .startWith([])
    .pairwise()
    .flatMap([prev, curr] => {
        // generate list of "added" and "removed" ids
        const added = curr.filter(id => prev.indexOf(id) === -1);
        const removed = prev.filter(id => curr.indexOf(id) === -1);

        // only emit ids when they are added and later removed
        return added.concat(removed);
    })
    .groupByUntil(
        id => id, // key selector
        null, // no need for element selector
        ids => ids.skip(1)) // end the group when the id is seen 2nd time (e.g. removed)
    .map(group => group.key)
    .flatMap(id => doUpdate(id));

这可能会有所帮助,但并没有解决订阅应该重用的根本问题。我现在拥有的最好的解决方案是使用缓存并在
最终发布
。什么订阅?在哪个窗口上重复使用?由
onUpdated
生成的可观察返回将由
combinelatetest
merge
或任何组合器订阅。当更改
flatMapLatest
的值时,所有订阅都将被丢弃,并创建全新的订阅。类似的东西可以工作,但非常难看…啊,那么您希望继续订阅每个id的“当前”可观察项,直到该可观察项完成或新版本的阵列中缺少该id为止?