Использовать 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
работать вместе?
Ответы
Ответ 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)
}