redux observable使用RxJS为ajax调用发出进度动作

redux observable使用RxJS为ajax调用发出进度动作,redux,rxjs,redux-observable,Redux,Rxjs,Redux Observable,我一直在努力解决这个问题,感觉自己有一个根本性的误解。我正在使用React中的redux observable库,它将redux与RxJS粘合在一起,用于处理异步。我的问题是,我必须处理一个大的上传,我想在文件加载时显示进度 函数uploadFileEpic需要返回一个Observable来使用redux Observable。uploadObservable表示我想要完成的工作流。如果我只是返回uploadObservable上传工作,但我没有从ajax调用中的progressSubscrib

我一直在努力解决这个问题,感觉自己有一个根本性的误解。我正在使用
React
中的
redux observable
库,它将
redux
RxJS
粘合在一起,用于处理异步。我的问题是,我必须处理一个大的上传,我想在文件加载时显示进度

函数
uploadFileEpic
需要返回一个
Observable
来使用
redux Observable
uploadObservable
表示我想要完成的工作流。如果我只是返回
uploadObservable
上传工作,但我没有从
ajax
调用中的
progressSubscriber
获取任何
handleUploadFileProgress
操作。理想情况下,
progressSubscriber
将向另一个可观察对象添加元素,我可以将其与
uploadObservable
合并。您看到我试图在这里使用
merge
,但是TypeScript编译器抱怨说返回值不可分配给
可观察输入

我一直在兜圈子,所以我觉得我的理解必须从根本上偏离。我觉得这里缺少了一些简单的
RxJS
magic。谢谢你的帮助

import { Observable, Observer, Subscriber, Subject, of } from 'rxjs';
import { ajax } from 'rxjs/ajax';
import { ofType } from 'redux-observable';
import { catchError, delay, map, mergeMap, tap, merge } from 'rxjs/operators';
import { apis } from '../../config';

export const enum ActionType {
  InitialFileUpload
  FileProgress
  UploadFileSuccess
  UploadFileFail
}

const handleInitialFileUpload = (file: File, timeLimit: number) => ({
  type: ActionType.InitialFileUpload,
  file,
  timeLimit
})

const handleFileProgress = (file: File, percentComplete: number) => ({
  type: ActionType.FileProgress,
  file,
  percentComplete
})

const handleUploadFileSuccess = (file: File, timeLimit: number) => ({
  type: ActionType.UploadFileSuccess,
  file,
  timeLimit
})

const handleUploadFileFail = (file: File, timeLimit: number) => ({
  type: ActionType.UploadFileFail,
  file,
  timeLimit
})


export const uploadFileEpic= action$ =>
  action$.pipe(
    ofType(ActionType.InitialFileUpload),
    mergeMap((action: any) => {
      const { file, timeLimit } = action;
      const data = new FormData()
      data.append('importFile', file, file.name)
      data.append('timeLimit', timeLimit)
      const progressSubject = new Subject();

      const ajaxRequest = {
        url: apis.gateway.run,
        method: 'POST',
        body: data,
        headers: {},
        progressSubscriber: Subscriber.create(
          (e: ProgressEvent) => {
            const percentComplete = Math.round((e.loaded / e.total) * 100)
            console.log("Progress event")
            progressSubject.next(handleUploadFileProgress(file, percentComplete))
          }
        )
      }

      const uploadObservable = ajax(ajaxRequest)
        .pipe(
          map(res => handleUploadFileSuccess(file)),
          delay(SUCCESSFUL_UPLOAD_NOTIFICATION_LENGTH),
          map(() => handleUploadFileRemove(file)),
          catchError(error => of(handleUploadFileFail(file, error.response)))
        )

      return merge(uploadObservable, progressSubject)
      }
    )
  )

您似乎正在从
rxjs/operators
导入
merge
。在那里,
merge
被视为运算符,因此返回一个
OperatorFunction
。通过简单地从
rxjs
导入,您可以得到一个静态合并,它正确地返回一个
可观察的
,它将被您的
mergeMap
压平