Подтвердить что ты не робот

Использовать async ждут с помощью Array.map

С учетом следующего кода:

var arr = [1,2,3,4,5];

var results: number[] = await arr.map(async (item): Promise<number> => {
        await callAsynchronousOperation(item);
        return item + 1;
    });

который вызывает следующую ошибку:

TS2322: Тип 'Promise <number> []' не может быть присвоен типу 'number []'. Введите "Promise <number> не присваивается типу 'number'.

Как я могу это исправить? Как я могу сделать async await и Array.map работать вместе?

4b9b3361

Ответ 1

Проблема в том, что вы пытаетесь await массива. Это не делает то, что вы ожидаете.

Когда объект, переданный в await, не является Promise, await просто возвращает значение as-is немедленно, а не пытается его решить. Так как вы передали await массив (объектов Promise) здесь вместо Promise, значение, возвращаемое await, - это просто тот массив, который имеет тип Promise<number>[].

Что вам нужно сделать, это вызвать Promise.all в массиве, возвращаемом map, чтобы преобразовать его в одно обещание перед await ing.

В соответствии с MDN docs для Promise.all:

Метод Promise.all(iterable) возвращает обещание, которое разрешает когда все promises в итерируемом аргументе разрешены или отвергает по причине первого обещанного обещания, которое отвергает.

Итак, в вашем случае:

var arr = [1, 2, 3, 4, 5];

var results: number[] = await Promise.all(arr.map(async (item): Promise<number> => {
    await callAsynchronousOperation(item);
    return item + 1;
}));

Это решит конкретную ошибку, с которой вы сталкиваетесь здесь.

Ответ 2

Если вы сопоставляете массив из Promises, вы можете разрешить их все в массив чисел. См. Promise.all.

Ответ 3

Там есть другое решение.

Вы также можете попробовать Promise.map(), смешав array.map и Promise.all

В вашем случае:

  var arr = [1,2,3,4,5];

  var results: number[] = await Promise.map(arr, async (item): Promise<number> => {
    await callAsynchronousOperation(item);
    return item + 1;
  });

Ответ 4

Я бы рекомендовал использовать Promise.all, как упоминалось выше, но если вам действительно нравится избегать этого подхода, вы можете сделать для или любой другой цикл:

const arr = [1,2,3,4,5];
let resultingArr = [];
for (let i in arr){
  await callAsynchronousOperation(i);
  resultingArr.push(i + 1)
}