javascript - 如何处理 redux-observable 中的异步函数?

标签 javascript redux rxjs rxjs5 redux-observable

我正在使用 RxJS 和 redux-observable。

我正在尝试读取史诗文件。就我而言,我必须在史诗中这样做,因为其他一些史诗会通过 expand 运算符多次“未知”触发该史诗。

但是由于 FileReader 是异步的,所以下面的代码不起作用。

处理这个问题的正确方法是什么,尤其是 RxJS 方法?谢谢

export const uploadAttachmentEpic = (action$, store) =>
  action$
    .ofType(UPLOAD_ATTACHMENT)
    .map(action => {
      const reader = new FileReader();

      reader.onload = () => {
        return {
          ...action,
          payload: {
            ...action.payload,
            base64: reader.result
          }
        }
      };

      reader.readAsDataURL(action.payload.file);
    })
    .mergeMap(action =>
      ajax
        .post( /* use action.payload.base64 */ )
        .map(uploadAttachmentSucceed)
        .catch(uploadAttachmentFailed)
    );

最佳答案

粉丝的回答(截至撰写本文时)很好,但有一些重要的注意事项:

  • 它会立即开始读取文件,而不是延迟读取。因此,甚至在任何人订阅之前调用 readFile(file) 就可以启动它。这很容易出错,因为有人可能不会立即同步订阅它,然后 reader.onload 就会错过它。理想情况下,Observable 是完全懒惰且可重复的工厂。

  • 它从不调用观察者的 obs.complete(),因此订阅可能会发生内存泄漏,因为它永远不会结束。

  • 观察器上的方法未绑定(bind),因此 reader.onerror = obs.error 实际上不会起作用。相反,您需要 e => obs.error(e)obs.error.bind(obs) See here for reference on why

  • 它不会在取消订阅时中止阅读。

这是我的做法:

function readFile(file){
  // Could use Observable.create (same thing) but I
  // prefer this one because Observable.create is
  // not part of the TC39 proposal
  return new Observable(observer => {
    const reader = new FileReader();
    reader.onload = (e) => {
      observer.next(reader.result);
      // It's important to complete() otherwise this
      // subscription might get leaked because it
      // "never ends"
      observer.complete();
    };
    reader.onerror = e => observer.error(e);
    reader.readAsDataURL(file);

    // unsubscribe handler aka cleanup
    return () => {
      // LOADING state.
      // Calling abort() any other time
      // will throw an exception.
      if (reader.readyState === 1) {
        reader.abort();
      }
    };
  });
}

这种模式几乎可以应用于任何 API,因此很容易理解它的工作原理。


希望范主不介意批评!我没有冒犯的意思,只是想分享知识。

关于javascript - 如何处理 redux-observable 中的异步函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47503668/

相关文章:

javascript - 如果传递模型,属于渲染助手的 Controller 将被重置

javascript - Vue.js - 加载服务 - Element UI

javascript - redux-simple-router - 基于 URL 执行操作

javascript - 不变违规 : Element type is invalid: expected a string or a class/function but got: object

angular - Angular 中的延迟 HTTP 请求

javascript - 在 RxJS mergeMap 之间导航时如何避免多次 HttpInterceptor 调用?

javascript - 使用 jquery 隐藏和显示内容

javascript - axios从v0.27.2升级到v1.1.2后出现错误

javascript - 在 Redux 操作中将数据放入 "payload"键有什么好处?

Angular 6 - 每 10 秒运行一次服务方法