Я использую пакет из npm для очистки метаданных с URL-адреса с именем метаданные URL. то, что я пытаюсь сделать, это просмотреть список ссылок json и очистить метаданные от каждой ссылки.
код
doc.edited_feed.items.forEach(item => {
// get metadata of each item link
urlMetadata(item.link).then(metadata => {
// add new item to the feed with the scraped metadata.image
console.info("running urlmetadata function")
feed1.addItem({
title: item.title,
link: url,
description: item.contentSnippet,
content: item.content,
id: item.link,
date: new Date(item.isoDate),
image: metadata.image
});
});
}
}); // End Foreach
console.info("after foreach block");
response.type("application/xml");
response.send(feed1.rss2());
Проблема в том, что функция metadataurl запускается после отправки ответа
выход
After foreach block
running urlmetadata function
running urlmetadata function
running urlmetadata function
что прямо противоположно тому, что я написал я предполагаю, что это как-то связано с асинхронной функцией или обещанием
Любая помощь, пожалуйста:/?
Если я помещу туда response.send(), он соскребет метаданные первой ссылки, а не всех остальных ссылок.
Правильно, вы должны перейти по ссылке, упомянутой @ponury-kostek, и изменить forEach на цикл for или for-of.



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


Создайте асинхронную функцию и ожидайте каждого ответа в цикле for
const funcName = async (items) => {
for (let i = 0; i < items.length; i++) {
let metadata = await urlMetadata(item.link);
// do stuff with metadata
}
}
Как минимум, Promise — это объект с методом then, который принимает функцию обратного вызова для работы с возвращаемым конечным значением. ...
Я рекомендую вам использовать синхронную выборку для вашей ситуации
Обещание работает как гонка между разрешением/отклонением и затем. Он отслеживает собственное состояние выполнения закрытия, зная, находится ли оно в ожидании, разрешено или отклонено.
(async () => {
try {
console.info("Start");
for (let index = 0; index < doc.edited_feed.items.length; index++) {
const item = doc.edited_feed.items[index];
const metadata = await urlMetadata(item.link);
feed1.addItem({
title: item.title,
link: url,
description: item.contentSnippet,
content: item.content,
id: url,
date: new Date(item.isoDate),
image: metadata.image
});
console.info(metadata.image, "hellooooooooo");
}
response.type("application/xml");
response.send(feed1.rss2());
console.info("End");
} catch (e) {
console.info(e);
}
})();
Ваша догадка (почти) верна. Функция urlMetadata НЕ ЗАПУСКАЕТСЯ после отправки ответа, а завершается после отправки ответа. Это связано с асинхронным характером вызова функции. Решение: поместите response.send() в часть обещания .then().