如何同步执行异步代码Angular 5

时间:2018-09-04 10:13:26

标签: angular typescript asynchronous

我有一个遍历文件列表的函数,然后对每个文件调用一个异步方法,该方法会进行一些图像处理,然后将图像推入数组。

问题在于异步调用是同时发生的,因此它锁定了UI。因此,我想遍历该列表,但仅在上一个函数完成时才调用该函数。

Array.from(files).forEach(data => {
    if (data.size > 5000000) {
        this.toastr_service.error('FILE ' + data.name + ' EXCEEDS FILE SIZE LIMIT (5MB)');
    }else {
        this.asyncFunc(data).subscribe(result => {
            this._photos.push(result);
        }, error => {
            console.log(error);
        });
    }
});

3 个答案:

答案 0 :(得分:2)

使用数组的map函数以及RxJS的forkJoin

forkJoin(Array
  .from(files)
  .map(file => file.size < 5000000 && this.asyncFunc(file) || undefined)
  .filter(value => !!value)
).subscribe(([...responses]) => {
  console.log(responses);
  this._photos.push(...responses);
});

forkJoin将在文件大小小于5Mb的情况下进行所有呼叫(mapfilter会处理此呼叫),并且在完成所有呼叫后,将推送响应进入您的数组。

编辑:如果要对呼叫进行排序,请使用concat

concat(...Array
  .from(files)
  .map(file => file.size < 5000000 && this.asyncFunc(file) || undefined)
  .filter(value => !!value)
).subscribe((...responses) => {
  this._photos.push(...responses);
  console.log(this.photos);
});

答案 1 :(得分:0)

测试此解决方案?

Array.from(files).flatMap(async data => {
  const result = await asyncFunc(data);
  this._photos.push(result);
});

答案 2 :(得分:-2)

您可以为其创建递归方法。

假设我们有一个json数组

     let array = [{key : xyz, id: xyz}, {key : abc, id: abc}]

        methodOnEvent(){
        this.iteratearraySync(0); // 0 is the index of array
        }
        iteratearraySync(index){

        if(this.array.length >0 && index <= this.array.length){
        // run your logic and after or inside callback recall the same method
if (data.size > 5000000) {
        this.toastr_service.error('FILE ' + data.name + ' EXCEEDS FILE SIZE LIMIT (5MB)');
iteratearraySync(index+1);
    }else {
        this.asyncFunc(data).subscribe(result => {
            this._photos.push(result);
iteratearraySync(index+1);
        }, error => {
            console.log(error);
iteratearraySync(index+1);
        });
    }

        }

    }