Используйте петлю for
вместо .forEach()
.Цикл for
будет приостановлен на время ожидания, цикл .forEach()
не будет.Это происходит потому, что обратный вызов async
, который вы передаете .forEach()
, вернет обещание, но .forEach()
не предназначен для того, чтобы что-то делать с этим обещанием, поэтому он не ожидает его разрешения, прежде чем продолжить цикл, а for
цикл с использованием await
делает.
Тогда getProductDataFromManyDomains()
должен быть async
и вернет обещание с вашим окончательным результатом.
async function getProductDataFromManyDomains(productNum) {
let prodData = {
reviews: []
}
const appCountries = [
{countryCode: 'nl'},
{countryCode: 'pl'},
{countryCode: 'de'}
]
for (let countryApp of appCountries) {
let countryData = {}
let parsedWebPage = await scrapWebPage(countryApp, productNum)
countryData.countryCode = countryApp.countryCode
countryData.ratingCount = parsedWebPage.aggregateRating.ratingCount
countryData.ratingValue = parsedWebPage.aggregateRating.ratingValue
countryData.reviews = parsedWebPage.reviews
prodData.reviews.push(countryData)
})
// this will be the resolved value of the promise that
// getProductDataFromManyDomains() returns
return prodData;
}
// usage
getProductDataFromManyDomains(productNum).then(result => {
console.log(result);
});
Вы также можете запускать несколько запросов параллельно, а не по одному, но, поскольку вы изначально пытались заставить свой код выполнять их по одному, я показал вам, как это сделать.
Если вы хотите выполнять их параллельно, вы просто накапливаете обещания в массиве и используете Promise.all()
, чтобы узнать, когда они все выполнены, и вы не await
запросите.
Вот версия кода, который выполняет запросы параллельно, используя .map()
и Promise.all()
:
function getProductDataFromManyDomains(productNum) {
let prodData = {
reviews: []
}
const appCountries = [
{countryCode: 'nl'},
{countryCode: 'pl'},
{countryCode: 'de'}
]
return Promise.all(appCounteries.map(countryApp => {
return scrapWebPage(countryApp, productNum).then(parsedWebPage => {
let countryData = {}
countryData.countryCode = countryApp.countryCode
countryData.ratingCount = parsedWebPage.aggregateRating.ratingCount
countryData.ratingValue = parsedWebPage.aggregateRating.ratingValue
countryData.reviews = parsedWebPage.reviews
return countryData;
});
})).then(results => {
// put results into prodData and make that the resolved value
prodData.reviews = results;
return prodData;
});
}
getProductDataFromManyDomains(productNum).then(result => {
console.log(result);
});