Учитывая следующий код:
var arr = [1,2,3,4,5];
var results: number[] = await arr.map(async (item): Promise<number> => {
await callAsynchronousOperation(item);
return item + 1;
});
которая выдает следующую ошибку:
TS2322: Тип «Обещание <номер> []» нельзя назначить типу «номер []». Тип «Обещание <номер> нельзя назначить типу« номер ».
Как я могу это исправить? Как я могу сделать async await
и Array.map
работать вместе?
arr.map()
является синхронным и не возвращает обещание.map
, которая ожидает синхронную операцию и ожидает, что она будет работать.async
, вы заставляете эту функцию возвращать обещание. Поэтому, конечно, карта асинхронности возвращает массив обещаний :)Ответы:
Проблема здесь в том, что вы пытаетесь
await
получить массив обещаний, а не обещаний. Это не делает то, что вы ожидаете.Когда переданный объект
await
не является Обещанием, онawait
просто возвращает значение как есть, а не пытается его разрешить. Таким образом, поскольку вы передалиawait
здесь массив (объектов Promise) вместо Promise, значение, возвращаемое await, является просто тем массивом, который имеет типPromise<number>[]
.Здесь вам нужно вызвать
Promise.all
массив, возвращаемый дляmap
того, чтобы преобразовать его в один Promise передawait
его использованием.Согласно документам MDN для
Promise.all
:Итак, в вашем случае:
Это устранит конкретную ошибку, с которой вы столкнулись здесь.
источник
:
означают двоеточия?callAsynchronousOperation(item);
с и безawait
внутри функции асинхронной карты?await
функция будет ожидать завершения (или сбоя) асинхронной операции, прежде чем продолжить, в противном случае она будет просто немедленно продолжена без ожидания.Есть и другое решение, если вы используете не собственные обещания, а Bluebird.
Вы также можете попробовать использовать Promise.map () , смешивая array.map и Promise.all
В вашем случае:
источник
Promise.mapSeries
илиPromise.each
являются последовательными,Promise.map
запускает их все сразу.concurrency
опцию.Если вы сопоставите массив с Обещаниями, вы сможете преобразовать их в массив чисел. Смотрите Promise.all .
источник
Я бы рекомендовал использовать Promise.all, как упомянуто выше, но если вы действительно хотите избежать такого подхода, вы можете сделать цикл for или любой другой цикл:
источник
Решение ниже, чтобы обработать все элементы массива асинхронно И сохранить порядок:
Также codepen .
Обратите внимание, что мы только «ждем» Promise.all. Мы вызываем calc без «await» несколько раз и сразу собираем массив нерешенных обещаний. Затем Promise.all ожидает разрешения всех из них и возвращает массив с разрешенными значениями по порядку.
источник