我一直在努力解决这个问题,觉得自己有一个基本的误解。我正在使用redux-observable
中的React
库,该库将redux
与RxJS
粘合在一起以处理异步。我的问题是我必须处理大量上载,并且要在加载文件时显示进度。
函数uploadFileEpic
需要返回一个Observable<Action>
才能与redux-observable
一起使用。 uploadObservable
代表我要完成的工作流程。如果我只返回uploadObservable
,则上传成功,但在handleUploadFileProgress
调用中没有从progressSubscriber
收到任何ajax
动作。理想情况下,progressSubscriber
将元素添加到另一个我可以与uploadObservable
合并的观察对象中。您看到我在这里尝试使用merge
,但是TypeScript编译器抱怨说该返回值无法分配给ObservableInput
。
我一直绕圈子走,所以我觉得我的理解必须从根本上偏离。我觉得这里缺少一些简单的RxJS
魔术。感谢您的帮助!
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)
}
)
)
答案 0 :(得分:0)
您似乎正在从merge
导入rxjs/operators
。此处,merge
被视为运算符,因此返回OperatorFunction
。通过简单地从rxjs
进行导入,您将获得静态合并,该合并正确地返回了Observable
,该合并将由您的mergeMap
展平。