如何在forEach循环Angular 6中进行同步调用

时间:2019-07-22 09:13:28

标签: javascript angular typescript angular6

我正在尝试检查所有4张图像均已上传到服务器,没有任何错误,然后重定向到另一个页面,因此我尝试在我的代码中执行一些同步检查(我的 imgResultAfterCompress数组中总共有4张图像)。下面是我的代码:

if(Boolean(this.updateImage(data.AddId))===true)
    {
     this.router.navigate(['/job-in-hotels-india-abroad']);
    }
updateImage(AddId:number):Observable<boolean> 
{
  this.cnt=0;
  this.uploadingMsg='Uploading Images...';
        this.imgResultAfterCompress.forEach( (value, key) => {

          if(value!=='')
          {

        this.itemService.updateImage(this.employer.ID,AddId,key,value).subscribe(data=>{
          if(data && data.status == 'success') {
            this.uploadingMsg=this.uploadingMsg+'<br>Image No - '+(key+1)+' Uploaded.';  
            this.cnt++;
            }
            else
              this.alertService.error(data.message);

          });
          }
          if(this.cnt==4)
          this.uploadingDone= true;
          else
          this.uploadingDone= false
        }); 
        return this.uploadingDone;
}   

每次我获得 cnt 值为0,我希望其值= 4(完全上传所有图像)时,就会发生重定向。

3 个答案:

答案 0 :(得分:2)

更简单的方法是使用zip运算符将您的可观察对象包装为一个对象

https://rxjs-dev.firebaseapp.com/api/index/function/zip

因此,每个请求成功完成后,您可压缩的Observable便会实现。

更新:

这就是我认为的样子。我可能会漏掉一些具体的东西,但是全球思路应该很清楚

    redirect() {
        this.updateImages(data.AddId).subscribe(
            () => this.router.navigate(['/job-in-hotels-india-abroad']),
            error => this.alertService.error(error.message)
        )
    }


    updateImages(AddId: number): Observable<boolean[]> {
        this.uploadingMsg = 'Uploading Images...';
        const requests: Observable<boolean>[] = [];

        this.imgResultAfterCompress.forEach((value, key) => {
            if (!value) {
                return;
            }

            requests.push(
                this.itemService.updateImage(this.employer.ID, AddId, key, value)
                    .pipe(
                        tap(() => this.uploadingMsg = this.uploadingMsg + '<br>Image No - ' + (key + 1) + ' Uploaded.'),
                        switchMap((data) => {
                            if (data && data.status == 'success') {
                                return of(true)
                            } else {
                                throwError(new Error('Failed to upload image'));
                            }
                        })
                    )
            )
        });
        return zip(...requests);
    }

答案 1 :(得分:0)

最后通过使用 forkJoin

获得了所需的结果

Service.ts:

public requestDataFromMultipleSources(EmpId: number,AddId:number,myFiles:any): Observable<any[]> {
    let response: any[] = [];
    myFile.forEach(( value, key ) => {
    response.push(this.http.post<any>(this.baseUrl + 'furniture.php', {EmpId: EmpId, AddId:AddId,ImgIndex:key,option: 'updateAdImg', myFile:value}));
    });
    // Observable.forkJoin (RxJS 5) changes to just forkJoin() in RxJS 6
    return forkJoin(response);
  }

my.component.ts

let resCnt=0;
this.itemService.requestDataFromMultipleSources(this.employer.ID,AddId,this.imgResultAfterCompress).subscribe(responseList => {
responseList.forEach( value => {
  if(value.status=='success')
   {
   resCnt++;
   this.uploadingMsg=this.uploadingMsg+'<br>Image No - '+(value.ImgIndex+1)+' Uploaded.';  
   }
   else
   this.uploadingMsg=this.uploadingMsg+'<br>Problem In Uploading Image No - '+(value.ImgIndex+1)+', Please choose another one.';  
 });

if(resCnt === this.imgResultAfterCompress.length)
{
  this.alertService.success('Add Posted Successfully');
  this.router.navigate(['/job-in-hotels-india-abroad']);
}
else
this.alertService.error('Problem In Uploading Your Images'); 
});

答案 2 :(得分:-2)

您不应尝试在循环中进行同步通话。可以使用return,但这对应用程序性能不利,并且是常见的反模式。

查看async/await。您可以将每个呼叫包装为promise,并在所有promise都解决后重定向。 https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/all