简体   繁体   English

通过 angular Http 依次(串行)在 angular 中使用 Z3E882BF1F2F60486B8F4E95Z 操作符 concat2F60486B8F4E96F 一个接一个地发送文件

[英]Send files over angular Http sequentially (serially) one by one in angular using rxjs concatMap() operator

I'm trying to upload files using a prefetchedUrl to S3 bucket sequentially.我正在尝试使用 prefetchedUrl 按顺序将文件上传到 S3 存储桶。

generateUrl() function used to generate a unique url for each file to be upload. generateUrl() function 用于为每个要上传的文件生成唯一的 url。 It takes a uniqueId (which is static) and a filename它需要一个 uniqueId(它是静态的)和一个文件名

  generateUrl(uniqueId, file) {
    var ext = (file.name).split(/\.(?=[^\.]+$)/);
    console.log(ext);
    return this.http.get<any>(`${this.baseURL}/v1/secure/upload/signed/${uniqueId}?filename=${file.name}.${ext}`);
  }

fileUpload() function used to upload files. fileUpload() function 用于上传文件。 It takes unique url generated by the generateUrl() function and a file to be uploaded.它需要由 generateUrl() function 生成的唯一 url 和要上传的文件。

  uploadFilesByLink(url, file) {
    return this.http.put(url,file, {
      headers: { "Content-Type": file.type },
      reportProgress: true,
      observe:'events'
    })
  }

Now what I'm trying to do is -现在我想做的是——

this.filesArray.forEach((file,index)=>{
     this.uploadsService.generateUrl(this.uniqueId, file)
        .pipe(
          concatMap(res1 => this.uploadsService.uploadFilesByLink(res1.url, file))
        ).subscribe(res2 => console.log(this.filesArray.indexOf(file),res2));
     })

But this is uploading files parallely.但这是并行上传文件。 Please help.请帮忙。 I have tried many solutions on google.我在谷歌上尝试了很多解决方案。

You could try to use RxJS from function along with the concatMap operator.您可以尝试使用 function from RxJS 和concatMap运算符。 from emits items in an array one by one as opposed to RxJS of function which doesn't flatten the input and emits the array as a single notification. from一个一个地发出数组中的项目,而不是 function of RxJS 不会展平输入并将数组作为单个通知发出。

Try the following尝试以下

from(this.filesArray).pipe(
  concatMap(file => {
    const url = this.uploadsService.generateUrl(this.uniqueId, file);
    return this.uploadsService.uploadFilesByLink(url, file);
  })
).subscribe(
  res => console.log(res),
  err => // always good practice to handle HTTP errors,
  () => console.log('complete')
);

I tried this way and its working.我试过这种方式及其工作。

upload.service.ts上传.service.ts

  generateUrl(uniqueId, file) {
    console.log(file);
    var ext = (file.name).split(/\.(?=[^\.]+$)/);
    console.log(ext);
    return this.http.get<any>(`${this.baseURL}/v1/secure/upload/signed/${uniqueId}?filename=${file.name}.${ext}`)
      .pipe(
        map(
          res => {
           return {
             "url": res.url,
             "file":file
            }
          }
        )
      )
  }

upload-home.component.ts上传-home.component.ts

 this.subscription = from(this.filesArray).pipe(
      concatMap(file => this.uploadsService.generateUrl(this.uniqueId, file)),
      concatMap(response => this.uploadsService.uploadFilesByLink(response.url, response.file))
    ).subscribe((event: HttpEvent<any>) => {

      switch (event.type) {
        case HttpEventType.Sent:
          console.log(' sent');
          break;
        case HttpEventType.ResponseHeader:
          console.log(' response header has been received');
          break;
        case HttpEventType.UploadProgress:
          // this.eventLoaded = event.loaded;
          this.progressInfo[this.it] = Math.round((event.loaded / event.total) * 100);
          console.log(event.loaded / event.total * 100);
          break;
        case HttpEventType.Response:
          // this.eventLoaded1 += this.eventLoaded;
          this.it++;
          console.log('it', this.it);

          this.responseArray.push(this.it);

          console.log('Uploaded');
          console.log(this.responseArray);

          // console.log(this.responseArray.length, this.filesArray.length);

          if (this.responseArray.length === this.filesArray.length) {
            console.log(this.emailOptions);

            if (this.emailOptions) {
              const controls = this.formGroup.controls;
              const from_email = controls.email_from.value;
              const to_email = controls.email_to.value;
              const message = controls.message.value;
              this.uploadsService.uploadFilesByEmail({
                "from_email": from_email,
                "to_email": [to_email],
                "message": message
              }, this.uniqueId).then(res => {
                this.uploadsService.afterUpdatingEmail(this.uniqueId).then(res => {
                  console.log('Uploaded By Email');

                  console.log(res);
                  this.it = 0;
                  this.filesArray = [];
                  this.fileSize = 0;
                  this.responseArray = [];
                  this.requestArrayLink = [];
                  this.subscription.unsubscribe();
                  this.successScreen = true;
                })
              })
            }
            else {
              this.it = 0;
              this.filesArray = [];
              this.fileSize = 0;
              this.responseArray = [];
              this.requestArrayLink = [];
              this.subscription.unsubscribe();
              console.log('Uploaded by Link');
              this.successScreen = true;
            }
          }
          else {
            console.log(this.it, 'uploaded');
          }
      }

    })
} 

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 Angular 6 + RxJs - concatMap 的错误处理 - Angular 6 + RxJs - Error handling for concatMap angular rxjs:关于管道/concatMap 内http 错误的访问参数? - angular rxjs: access parameter on http error inside pipe/concatMap? Angular 8 RXJS - 按顺序进行多个 HTTP 调用 - Angular 8 RXJS - Make multiple HTTP calls sequentially 在 angular、rxjs 中依次发出两个 http 请求 - Making two http requests sequentially in angular, rxjs 用rxjs依次调用api - call api serially in angular with rxjs How to avoid nested subscriptions in Angular / RxJS - One call after another call (sequentially / not parallel) And looping http api calls - How to avoid nested subscriptions in Angular / RxJS - One call after another call (sequentially / not parallel) And looping http api calls 使用 rxjs 运算符成功后发送副作用 http 请求 - Send a side effect http request after a successful one using rxjs operator Angular 5 RxJs concatMap、switchMap、mergeMap 哪个? - Angular 5 RxJs concatMap,switchMap,mergeMap which? 如何在 RXJS Angular 中的 concatmap 之间传递数据 - how to pass data between concatmap in RXJS Angular Angular-正确使用RXJS扩展运算符进行递归http调用 - Angular - Correctly using RXJS expand operator to make recursive http calls
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM