angular - 如何手动完成 angular http observable
问题描述
我正在开发多个并行文件上传功能,能够删除/取消正在进行的 http 调用。一旦所有呼叫完成/取消,我就会通知消费者。
为此,我使用forkJoin
. 但是如果用户点击取消按钮,我不应该等待实际 http 响应的完成。
takeUntill 不会优雅地处理它,因为它只会在从底层源 http 流接收到下一个值后才会采取行动。
this.uploadFiles().subscribe(data => {
console.warn("Upload completed now!!!!!", data);
});
uploadFiles() {
return forkJoin(
this.files.map(file => // returns array of observable
this.uploadFile(file).pipe( catchError(() => of("Error re-emitted as success to prevent early exit"))))
).pipe(map(() => {
// logic for some user friendly statistic
return data;
}));
}
解决方案
与 Subject 一起使用takeUntil
作为通知者来完成 Observables。您可以将文件 id 传递给 Subject 并使用filter
intakeUntil
仅取消具有给定 id 的文件的文件上传。
用于defaultIfEmpty
提供指示已取消请求的值。这也可以防止在forkJoin
内部空请求完成时外部立即完成。
private cancelUpload$ = new Subject<number>();
uploadFiles() {
let errorCount = 0, cancelledCount = 0, successCount = 0;
return forkJoin(this.dummyFiles.map(file =>
this.uploadFile(file).pipe(
// react to CANCEL event
map(response => response == 'CANCEL' ? ++cancelledCount : ++successCount),
catchError(() => of(++errorCount))
)
)).pipe(map(() => ({ errorCount, successCount, cancelledCount })));
}
uploadFile(file: any) {
http$.pipe(
...
takeUntil(this.cancelUpload$.pipe(filter(id => id == file.id))), // cancel
defaultIfEmpty('CANCEL'), // provide value when cancelled
)
}
cancelUpload(file: any) {
file.uploadStatus = "cancelled";
this.cancelUpload$.next(file.id) // cancel action
}
推荐阅读
- javascript - 在 react js 中访问 json 文件
- docker - buildozer 的 docker 容器内的权限被拒绝
- angularjs - 单击并在 Angular 中显示我的列表中的所有记录
- angular - Angular 4下拉菜单点击关闭
- javascript - 使用 Angular 5 指令从 JSON 对象创建动态表
- angular-material - 带有“搜索输入”作为最后一个选项卡的 Angular 材质选项卡
- c# - 如何在 App.config 上更改我的数据库文件的路径?
- php - PHP xPath 解析 SOAP
- seo - 每种语言一个站点地图图像,可能吗?
- python - 使用 Python 中已提供的参数创建一个可调用对象