在移动到下一个索引之前等待每个数组元素的订阅完成

Wait for subscription to finish for each array element before moving to the next index

我试图将多张图片上传到外部服务器,所以我在我的 FilesArray 中循环,在每个元素上我触发了一个 httpRequest 以将图片上传到服务器,我创建了一个进度条来通知用户上传进度,但问题是我的循环在移动到下一个索引之前不会等待每个元素结束其订阅,它会以并行方式触发 httpRequest,这是正常的,有没有办法等待每个元素订阅完成之前移动到下一个索引元素?

我的上传功能:

        let total = 0;
for (let index = 0; index < this.galleryPhotoFiles.length; index++) {

  this.galleryPhotosFormData.append("file", this.galleryPhotoFiles[index]);
  this.galleryPhotosFormData.append("upload_preset", [PRESET_NAME]);
  const req = new HttpRequest('POST', 'https://api.cloudinary.com/v1_1/[CLOUD_NAME]/image/upload', 
   this.galleryPhotosFormData,
    {
      headers: new HttpHeaders(),
      reportProgress: true,
    });


  this.http.request(req).subscribe(event => {

    if (event.type === HttpEventType.UploadProgress) {
      const percentDone = Math.round(100 * event.loaded / event.total);
      console.log(`File ${index} is ${percentDone}% uploaded.`);
    } else if (event instanceof HttpResponse) {
      console.log('File is completely uploaded!');
    }
  });

}

您可以通过 EventEmitter 创建自己的活动。例如:

  1. 调用第一张图片的上传功能(点击按钮或其他方式)- uploadImages()
  2. 图片上传完成后,发出事件 - this.fileUploaded.emit(index)
  3. 在事件处理函数中,上传下一张图片 - this.uploadImage(event + 1)

import { ..., EventEmitter } from '@angular/core';

...

    fileUploaded: EventEmitter<number>;
    
    ngOnInit(): void {
        this.fileUploaded = new EventEmitter<number>();
        this.fileUploaded.subscribe((event: number) => this.uploadImage(event + 1)); // register an event handler
    }
    
    uploadImages() { // on button click to upload images (assuming that's how you'd do it), you call this function
        this.uploadImage(0);
    }
    
    uploadImage(index: number) {
        if (index < 0 || index > this.galleryPhotoFiles.length) // important exit condition
          return;
    
        this.galleryPhotosFormData.append("file", this.galleryPhotoFiles[index]);
        this.galleryPhotosFormData.append("upload_preset", [PRESET_NAME]);
        const req = new HttpRequest('POST', 'https://api.cloudinary.com/v1_1/[CLOUD_NAME]/image/upload',
          this.galleryPhotosFormData,
          {
            headers: new HttpHeaders(),
            reportProgress: true,
          });
    
    
        this.http.request(req).subscribe(event => {
    
          if (event.type === HttpEventType.UploadProgress) {
            const percentDone = Math.round(100 * event.loaded / event.total);
            console.log(`File ${index} is ${percentDone}% uploaded.`);
          } else if (event instanceof HttpResponse) {
            console.log('File is completely uploaded!');
            this.fileUploaded.emit(index); // notify that the file with index 'index' has been uploaded completely 
          }
        });
    }