JavaScript 跟踪和关联多个异步事件

Posted

技术标签:

【中文标题】JavaScript 跟踪和关联多个异步事件【英文标题】:JavaScript keeping track and association of multiple asynchronious events 【发布时间】:2021-05-06 00:43:06 【问题描述】:

我正在编写一个 Angular 10 应用程序,它允许用户压缩图像并将其上传到 Google Cloud Storage。压缩和上传工作正常,但是,它是关联所有并发压缩和上传的异步部分。

跟踪每个文件的当前压缩和上传状态的最佳方法是什么?

类变量(例如对象数组)是向用户显示进度的理想选择。

我可以将一个对象推送到一个类 Array 但是我如何跟踪元素以在压缩完成后更新其状态并在上传开始后设置percentageChanges() observable?

我的代码如下所示,一旦用户在 html 文件输入中提交带有所选图像的表单,就会调用 processFileList()

 async compressAndUpload(file) 
   // Compress image, function not explained further, returns promise
   const compressed = await compressImage(file);

   // Create path
   const uploadPath: string = 'file' + (new Date()).getTime()
   
   // Upload image
   const imageUploadTask = this.storage.upload(uploadTask, compressed)
   
   // Current percentage of upload can be retrieved as observable
   const percentage = imageUploadTask.percentageChanges()



processFileList(fileList: FileList) 
    // Create array from FileList to be able to iterate
    const files = Array.from(fileList);
    
    files.forEach(file => 
        compressAndUpload(file);
    )
   

【问题讨论】:

使用一个类。使用.forEach( file => new CompressAndUpload(file)) 将您的课程实例化 n 次。在课堂内你可以去this.percentthis.timeRemaining等。 另外,processFileList 不需要是async,因为你没有在awaiting 里面写任何东西。 你可能根本不想使用 promises async-await 只是将所有内容转换为使用 observable 尤其是当你想要跟踪进度时,promise 在跟踪进度方面很糟糕。使用 rxjs,你可以合并一些 observable 并将它们的结果映射到一些报告对象 【参考方案1】:

如果你想跟踪进度,最好使用完整的 observable,特别是如果你在 Angular 框架中,你应该习惯使用 rxjs:

import  merge, from  from 'rxjs';
import  map, switchMap  from 'rxjs/operators';
//...
function compressAndUpload(file) 
   // ... setup uploadTask

  return from(compressImage(file))// preferably convert returned result to observable or cast it using from
    .pipe(
      switchMap((compressed) =>
        this.storage.upload(uploadTask, compressed).percentageChanges()
          .pipe(
            map(progress => ( file, progress ))
          )
      )
    )



function processFileList(fileList: FileList) 
  // Create array from FileList to be able to iterate
  const files = Array.from(fileList);

  return merge([...files.map(compressAndUpload)])


processFileList(someFileList)
  // implement your progress reporter on subsciption
  .subscribe(( file, progress) => console.log('Progress', progress, 'for file', file))

【讨论】:

以上是关于JavaScript 跟踪和关联多个异步事件的主要内容,如果未能解决你的问题,请参考以下文章

异步编程之事件循环机制

JS中的异步以及事件轮询机制

javascript 使用事件跟踪和jQuery跟踪Google Analytics中的传出链接

进阶学习5:JavaScript异步编程——同步模式异步模式调用栈工作线程消息队列事件循环回调函数

如何在 Objective-C 中管理、跟踪或同步多个服务器的异步请求?

Javascript 和 Phonegap 插件之间的异步通信