Rxjs 发送操作以响应取消

Rxjs 发送操作以响应取消,rxjs,redux-observable,Rxjs,Redux Observable,我从redux observable文档开始,并希望对其进行一些扩展 基本上,我有一个场景,在触发取消后,使用takeUntil我想调度另一个动作来清理,等等 这就是我到目前为止的想法: 启动“获取用户信息”,然后点击取消。我希望它按以下顺序执行操作: -USER/FETCH -请求/启动 -用户/取消 -请求/取消 这是我现在设置的方式。但是,我必须依赖于将dispatch传递到requestSequence函数中,然后在中最终触发它。是否有一种更干净的方法,仅使用可观察的操作符来实现这一点?

我从redux observable文档开始,并希望对其进行一些扩展

基本上,我有一个场景,在触发取消后,使用
takeUntil
我想调度另一个动作来清理,等等

这就是我到目前为止的想法:

启动“获取用户信息”,然后点击取消。我希望它按以下顺序执行操作:
-
USER/FETCH

-
请求/启动

-
用户/取消

-
请求/取消

这是我现在设置的方式。但是,我必须依赖于将
dispatch
传递到
requestSequence
函数中,然后在
中最终触发它。是否有一种更干净的方法,仅使用可观察的操作符来实现这一点?因此,当触发
USER.CANCELLED
时,一些最终操作映射到
requestSequence
可观察的内部


Redux logger已启用,因此请检查控制台中的所有操作。

而不是使用
.takeUntil()
,它听起来像是您想要使用的,它的名称相当恰当。无论哪条流先发出,都将获胜!另一个是取消订阅

你需要重新构造一些东西,才能随心所欲地使用它。您希望将立即发出的第一个操作,即您的
请求.onStart(meta)
,与ajax请求
Observable.fromPromise(apiCall(…args))分离开来
。然后,您希望直接在ajax和取消之间进行竞争,因此您需要传入
action$
ActionsObservable,因为这一切都在助手中


旁注:要小心过早的抽象,比如做那些助手。尽管你可能会在一些史诗中重复一些东西,但我发现,将其抽象化会使以后的摸索变得更加困难,特别是如果其他人没有编写代码,也不是Rx大师的话。当然,只有您才能知道这个建议是否适用于您和您的代码库

对我来说,最让人困惑的一点是你必须传递给
requestSequence
的所有参数,这对于许多人来说,当他们第一次遇到它时很难理解。如果您发现您的epic通常做完全相同的事情,并且希望重用,那么对整个epic进行抽象可能会更清楚,并创建API实用程序,如下面的
userRequest
,您可以独立测试

(未经测试,基本上是伪代码)


谢谢你的精彩解释
createApiEpic
方法看起来干净多了。
function requestSequence(apiCall, args, meta, action$) {
  return Observable.of(request.onStart(meta))
    .concat(
      Observable.fromPromise(apiCall(...args))
        .map((payload) => request.onSuccess(payload, meta))
        .catch((e) => Observable.of(request.onError(e, meta)))
        .race(
          action$.ofType(USER.CANCELLED)
            .map(() => request.onCancel(meta))
        )
    );
}

const fetchUserEpic = (action$, store) =>
  action$.ofType(USER.FETCH)
    .mergeMap(action =>
      requestSequence(
        userRequest, 
        [`/api/users/${action.payload}`],
        { activity: USER.FETCH, path: 'user' },
        action$
      )   
    );
const createApiEpic = options =>
  action$ =>
    action$.ofType(options.on)
      .mergeMap(action =>
        Observable.of(request.onStart(meta))
          .concat(
            options.effect(action.payload)
              .map(payload => request.onSuccess(payload, meta))
              .catch(e => Observable.of(request.onError(e, meta)))
              .race(
                action$.ofType(options.cancel)
                  .map(() => request.onCancel(meta))
              )
          )
      );

const userRequest = id =>
  Observable.ajax.getJSON(`/api/users/${id}`);

const fetchUserEpic = createApiEpic({
  on: USER.FETCH,
  effect: userRequest
  cancel: USER.CANCELLED
});