首页 > 解决方案 > 在 Angular 中调用下一个操作之前等待文件下载事件(Javascript)

问题描述

我有一个简单的用例如下 -

用户触发 REST API 调用来处理文件上传

文件在后端上传到云端

API 返回带有 URL的响应,用于下载文件,例如 -http://somedomain/fileName.zip

在客户端下载文件后,还有另一个 API 调用来更新数据库中下载文件的下载计数

这是Angular code在客户端使用实现的。

伪代码如下:

//Download Service Call to Download File . It returns Obseravable 
downloadService.downloadFile.subscribe(

(data: downloadData) => processDataDownload(data);
(err) => this.message = "Error Downloading File ";

);
//method processing file download and updating download count 
private processDataDownload(data : Response){

   this.downloadFile(data);
   this.updateDownloadCount(data);

}

//download a file using URL 
private downloadFile(data : Response) : void {
   //standard java script code to get file download using URL click     
    var a = document.createElement("a");
    a.href = data.downloadUrl;
    fileName = data.downloadUrl.split("/").pop();
    a.download = fileName;
    document.body.appendChild(a);
    a.click();
    window.URL.revokeObjectURL(url);
    a.remove();
}
//update download count 
private updateDownloadCount(data : Response ){
    //another http call to update download count for files 
}

现在,我的问题是:

1)有什么方法可以让updateDownloadCount方法仅在文件成功下载后才被调用?

2)含义,方法-中的java脚本代码,使用程序化URL点击downloadFile触发文件下载

3)我们可以等待这个下载发生然后打电话updateDownloadCount吗?

4)我们可以等待DOWNLOAD event completion然后触发数据库更新吗?

5)有什么办法可以做到这一点?

标签: javascriptangular

解决方案


我假设 downloadService.downloadFile 实际上并没有下载文件,而是下载文件详细信息,对吗?当您像在示例中那样创建下载 url 时,实际上是在告诉浏览器处理下载过程。如果您希望您的应用程序处理它,您需要采取稍微不同的方法。

您基本上想使用 Angular 的 HttpClient 从服务器获取文件 blob。您可以使用它来跟踪进度。完成后,您可以将确认发送到 API 并呈现内部下载链接。

就像是:

downloadFile(file) {
  return this.http.get(
    this.baseUrl + 'file.url', 
    {         
        responseType: 'blob',
        reportProgress: true,
        observe: 'events',          
    }
  );
}

在您的组件中,您可以订阅此下载并根据 HttpEventType.DownloadProgress 检查 result.type 以了解进度,或根据 HttpEventType.Response 检查下载完成情况。

this.service.downloadFile(myfile).subscribe(result => {
    if (result.type === HttpEventType.DownloadProgress) {
      ...calc percent
    }
    if (result.type === HttpEventType.Response) {
      ... this is where you create the blob download link and call your api
    }
});

推荐阅读