Как сделать асинхронный код синхронно Angular 5 - PullRequest
0 голосов
/ 04 сентября 2018

У меня есть функция, которая выполняет итерации по списку файлов, а затем для каждого файла она вызывает асинхронный метод, который выполняет некоторые манипуляции с изображениями, а затем помещает изображение в массив.

Проблема в том, что асинхронные вызовы происходят в одно и то же время, и поэтому он блокирует пользовательский интерфейс. Поэтому я хотел бы перебрать список, но вызывать функцию только после завершения предыдущего.

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 голосов
/ 04 сентября 2018

Используйте функцию map массивов, а также RxJS's 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 будет выполнять все вызовы, если размер файла меньше 5 МБ (map & filter позаботится об этом), и после выполнения всех вызовов ответы будут помещены в ваш массив.

РЕДАКТИРОВАТЬ Если вы хотите, чтобы ваши вызовы были упорядочены, используйте вместо этого 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);
});
0 голосов
/ 04 сентября 2018

Проверить это решение?

Array.from(files).flatMap(async data => {
  const result = await asyncFunc(data);
  this._photos.push(result);
});
0 голосов
/ 04 сентября 2018

Вы можете создать для него методы рекурсии.

предположим, у нас есть массив 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);
        });
    }

        }

    }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...