抽象问题:每次源 Observable 发出事件时,都需要触发一系列 API 调用和 Angular 服务。其中一些调用取决于之前的结果。
在我的示例中,源 ObservablestartUpload$
触发一系列依赖调用。
使用解构可以这样写:
this.startUploadEvent$.pipe(
concatMap(event => this.getAuthenticationHeaders(event)),
map(({ event, headers }) => this.generateUploadId(event, headers)),
tap(({ event, headers, id }) => this.emitUploadStartEvent(id, event)),
concatMap(({ event, headers, id }) => this.createPdfDocument(event, headers, id)),
concatMap(({ event, headers, id, pdfId }) => this.uploadBilderForPdf(event, pdfId, headers, id)),
mergeMap(({ event, headers, id, pdfId, cloudId }) => this.closePdf(cloudId, event, headers, id, pdfId)),
tap(({ event, headers, id, pdfId, cloudId }) => this.emitUploadDoneEvent(id, event, cloudId)),
).subscribe()
它读起来几乎像是一种命令式的方法。但它也存在一定的问题:
- 解构链在代码中不断重复,并且变得越来越长
{ event, headers, id, pdfId, cloudId }
- 方法(如
generateUploadId(event, headers)
)需要接收所有先前的值,以便它们能够将它们传递到下一个管道,即使方法本身不需要它
- 内部可观察对象(在方法内)需要映射值,以便进一步的管道阶段可以破坏它们:
_
private closePdf(cloudId, event, headers, id, pdfId) {
return this.httpClient.post(..., { headers } )
.pipe(
//...,
map(() => ({ event, headers, id, pdfId, cloudId }))
)
}
如果编译器能够处理样板文件(就像async await
)编写如下代码(没有上述问题):
private startUpload(event: StartUploadEvent) {
const headers = this.getAuthenticationHeaders(event)
const id = this.generateUploadId()
this.emitUploadStartEvent(id, event)
const pdfId = this.createPdfDocument(event, headers, id)
this.uploadBilderForPdf(event, pdfId, headers, id)
const cloudId = this.closePdf(headers, pdfId)
this.emitUploadDoneEvent(id, event, cloudId)
return cloudId
}
如何在链式可观察量之间传递结果而不出现我提到的问题?我错过了 rxjs 概念吗?