首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >我如何写使用以前返回的值的一个可观测的可还原-可观测?

我如何写使用以前返回的值的一个可观测的可还原-可观测?
EN

Stack Overflow用户
提问于 2018-01-02 19:23:02
回答 2查看 1K关注 0票数 1

我不知道我的题目是否适合这个问题。我希望使用someAsync1的返回值(与v2相同)作为action1在flatMap中的参数。

代码语言:javascript
复制
const anEpic = ($action: ActionsObservable<MyAction>, store: Store<MyRootStore>) => {
return $action.ofType(ActionTypes.AN_ASYNC_ACTION)
    .switchMap((v1) => someAsync1(v1)) 
    .switchMap((v2) => someAsync2(v2))
    .map((v) => applyToUI(v))
    .flatMap((v) => Observable.concat(Observable.of(action1(v)), Observable.of(action2(true)))) // 
}

我想我可以通过将v2注入someAsync2的返回值来使用这个值。但那密码看起来很恶心。有什么聪明的方法可以通过可观察到的方法来实现呢?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2018-01-03 03:29:52

从技术上讲,switchMap意味着,切换到另一个可观察到的流。这意味着你没有办法保留这个值,因为你的观察者现在正在观察一个不同的来源。

有几种方法可以实现所谓的“保留”从一个流到另一个流的值,这取决于您喜欢哪个流。

1.行为主体

这是最首选的方法,因为BehaviourSubject的目的是保留Observable的值。

代码语言:javascript
复制
//initialize a BehaviourSubject
let v2BSubject = new BehaviourSubject<any>(null);

const anEpic = ($action: ActionsObservable<MyAction>, store: Store<MyRootStore>) => {
    return $action.ofType(ActionTypes.AN_ASYNC_ACTION)
        .switchMap((v1) => someAsync1(v1))
        .switchMap((v2) => {
            //store your v2 value here!
            v2BSubject.next(v2);
            return someAsync2(v2)
        })
        .map((v) => applyToUI(v))
        .flatMap((v) => {
            //get your v2 values here
            let v2Value = v2BSubject.value;
            return Observable.concat(Observable.of(action1(v)), Observable.of(action2(true)))
        }) //
}

或者您可以使用它作为一个Observable。这样,您就可以将其视为可观察的,并使用rxjs操作符可以提供的任何内容:

代码语言:javascript
复制
.flatMap((v) => {
    return Observable.concat(Observable.of(action1(v)), v2BSubject.asObservable())
}) 

2.使用.map来传播该值。

这很烦人,但能把工作做完。但是,请注意,它正在修改流源。如果你在管道上有很多操作,它可能会很快爆炸,而且很难管理:

代码语言:javascript
复制
 const anEpic = ($action: ActionsObservable<MyAction>, store: Store<MyRootStore>) => {
    return $action.ofType(ActionTypes.AN_ASYNC_ACTION)
        .switchMap((v1) => someAsync1(v1))
        .switchMap((v2) => {
            someAsync2(v2)
                .map(afterSomeAsync2 => {
                    return {
                        v1Value: v2,
                        v2Value: afterSomeAsync2
                    }
                })
        })
        .map(({v1Value, v2Value}) => {
            return applyToUI(v1Value).map(v1 => {
                return {
                    v1Value: v1,
                    v2Value: v2Value
                }
            })
        })
        .flatMap(({v1Value, v2Value}) => {
            return Observable.concat(Observable.of(action1(v1Value)), Observable.of(v2Value))
        }) 
票数 3
EN

Stack Overflow用户

发布于 2018-01-04 19:33:41

最简单的解决方案是直接将运算符应用于返回的内部可观测值,而不是应用于折叠的外部链。然后,您可以访问发出的值,因为它们是闭包的一部分。

这可能会让人困惑,但希望这段代码能清楚地说明:

代码语言:javascript
复制
const anEpic = ($action: ActionsObservable<MyAction>, store: Store<MyRootStore>) => {
  return $action.ofType(ActionTypes.AN_ASYNC_ACTION)
    .switchMap((v1) =>
      someAsync1(v1)
        .switchMap((v2) =>
          someAsync2(v2)
            .map((v) => applyToUI(v))
            .flatMap((v) => Observable.of(action1(v, v1, v2), action2(true))
        )
    ) 
  }

如果希望通过someAsync1someAsync2捕获任何错误,则必须使用此模式,因为如果让错误传播到顶级链,epic将停止侦听未来的操作。

例如,如果你的史诗像这样:

代码语言:javascript
复制
const somethingEpic = (action$, store) => {
  return action$.ofType(SOMETHING)
    .switchMap(action => someAsync1(v1))
    .map(() => ({ type: SOMETHING_FULFILLED }))
    .catch(error => Observable.of({
      type: SOMETHING_REJECTED,
      error
    }));
  }

当错误到达catch操作符时为时已晚,您的epic将不再侦听未来的操作。您可以“重新启动”它,但这可能会产生意想不到的后果,因此最好避免这种模式。

相反,在错误传播之前捕获它。

代码语言:javascript
复制
const somethingEpic = (action$, store) => {
  return action$.ofType(SOMETHING)
    .switchMap(action =>
      someAsync1(v1)
        .map(() => ({ type: SOMETHING_FULFILLED }))
        .catch(error => Observable.of({
          type: SOMETHING_REJECTED,
          error
        }))
    );
  }

有些人把这称为“孤立你的观察者锁链”。

还请注意,我不需要将concat与多个of一起使用,因为of支持任意数量的参数。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/48066645

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档