【问题标题】:JavaScript keeping track and association of multiple asynchronious eventsJavaScript 跟踪和关联多个异步事件
【发布时间】: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 并将它们的结果映射到一些报告对象

标签: javascript angular typescript promise rxjs


【解决方案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))

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-07-10
    • 1970-01-01
    相关资源
    最近更新 更多