Angular/rxjs:显示下载进度+等待文件下载后再继续



在Ionic/Angular项目中,我有一系列HTTP请求,需要在继续之前完成。但我也需要在应用程序中向用户显示下载进度条。但我不知道在哪里或如何实现对HttpEvents的侦听,所以我可以显示加载进度。这就是我目前拥有的:

downloadDocument(document: Document) {
// does a http.get to get the documents url
return this.documentsRepositoryService.getDownloadUrl(document).pipe(
concatMap(
//the download url is received, now download the file.
// TODO: listen for download progress and display 0 - 100% 
// Should wait for download to complete
dlUrl => this.documentsRepositoryService.downloadDocument(document, dlUrl.url)
),
concatMap(
value => {
// do something with the downloaded file I suppose
// Update the documentstatus to "downloaded"
// returns promise, convert to observable
document.download(); // just sets the document's state as downloaded
return of(this.documentsRepositoryService.update(document));
}
),
concatMap(
value => {
// now do a httprequest to confirm to the api, the file is downloaded
return this.documentsRepositoryService.confirmDownloadToAPI(document);
}
),
concatMap(
value => {
// sequence is done.
this.setBadge();
return value;
}
)
)
}

该方法返回一个我订阅的可观察对象:

onDownload(document) {
this.downloadManager.downloadDocument(document).subscribe(
value => {
// currently runs 
console.log("downloaded");
}
);

}

此刻;下载的";console.log显示了两次,我怀疑是什么时候开始下载,什么时候结束?所以这不是正确的方法

我在这个主题上找到的几个例子在订阅中监听文档下载进度,但我不知道如何在管道中或至少在序列中这样做。还是这是实现这一目标的更好方法?

感谢

EDIT:仍然不是";作为最终对象的解决方案不会被接收,只有进度消息。

编辑2:找到它,下面的代码";更改";映射((中函数中字符串的结果。

我在官方文件中找到了答案。跑两次的错误是因为我没有使用";last(("在downloadFile方法中。它基本上发送了所有事件。现在报告进度。最后要做的是更改下面的代码,这样它就不会发送字符串,而是发送事件本身。

downloadFile(filesrc) {
const req = new HttpRequest('GET', filesrc, null, {
reportProgress: true,
responseType: 'blob'

});

return this.http.request(req).pipe(
map(event => this.getEventMessage(event)),
tap(message => this.showProgress(message)),
last(), // return last (completed) message to caller
);
}

showProgress(message ){
console.log(message);
}
getEventMessage(event: HttpEvent<any>) {
console.log('event is', event);
switch (event.type) {
case HttpEventType.Sent:

return `sending request`;
case HttpEventType.UploadProgress:
// Compute and show the % done:
const percentDone = Math.round(100 * event.loaded / event.total);

return `File is ${percentDone} uploaded.`;
case HttpEventType.Response:

return `File was completely uploaded!`;
case HttpEventType.DownloadProgress:
const percentDoneDL = Math.round(100 * event.loaded / event.total);

return `File is ${percentDoneDL} downloaded`;
case HttpEventType.ResponseHeader:

return `Response headers are received`
default:

return `File surprising upload event: ${event.type}.`;
}
}

最新更新