#javascript #node.js #async-await
Вопрос:
У меня есть массив объектов, содержащих метаданные для видео. Мне нужно повторить его, и для каждого объекта мне нужно выполнить вызов API, передающий его filename
, чтобы получить a streamingLink
и назначить его объекту streamingLink
. Моя проблема в том, что к тому времени, когда я возвращаю этот массив, массив не определен. Как мне сообщить коду, чтобы он подождал, пока streamingLink не будет назначен?
Вот как выглядит мой код:
// get array from database
const items = await client.db('database').collection('collection').find({}).toArray();
// for each object get and replace streamingLink
let items_withLinks = items.map((item) => {
getStreamingLink(item.filename) // API call to get link
.then(response => {
item.streamingLink = response.result.link;
return item;
})
});
console.log(items_withLinks); // undefined
Я пробовал использовать await
в разных местах и оборачивать это в async
функцию, но я не могу понять, как это правильно сделать.
Ответ №1:
Вы можете перебирать свой массив и создавать обещание для каждого элемента. Тогда ты можешь позвонить Обещанию.все.
const promise1 = Promise.resolve(3);
const promise2 = 42;
const promise3 = new Promise((resolve, reject) => {
setTimeout(resolve, 100, 'foo');
});
Promise.all([promise1, promise2, promise3]).then((values) => {
console.log(values);
});
// expected output: Array [3, 42, "foo"]
Ответ №2:
Основная проблема заключается в том, что функция, которую вы используете в .map
, ничего не возвращает. (Таким образом, вы фактически технически получите массив undefined
значений, а не undefined
сами по себе, но это, очевидно, никуда не годится.)
Вам нужно return
обещание, а затем использовать Promise.all
его для получения массива результатов.
// get array from database
const items = await client.db('database').collection('collection').find({}).toArray();
// for each object get and replace streamingLink
let items_withLinks = items.map((item) => {
// return is the only thing I've added here!
return getStreamingLink(item.filename) // API call to get link
.then(response => {
item.streamingLink = response.result.link;
return item;
})
});
const result = await Promise.all(items_withLinks);
console.log(result);
Комментарии:
1. Блестящий. Спасибо!!