从使用多个异步调用的函数返回

时间:2018-05-18 15:22:20

标签: javascript asynchronous promise async-await axios

所以基本的想法是编写一个方法来废弃网页以获取包含产品评级的JSON数据。然后在几个域(.de,.uk,.fr,.nl等)上多次调用此方法来收集所有评级。

所以我最终得到了scrapWebPage方法,它废弃了单页:

const scrapWebPage = async (countryAppData, productNumber) => {
    const shopUrl = `https://www.shopExample.${countryAppData.countryCode}/?q=${productNumber}`
    const avoidCORSUrl = 'https://allorigins.me/get?url=' + shopUrl + '&callback=?'

    return await axios
        .get(avoidCORSUrl, {xmlMode: false, normalizeWhitespace: true})
        .then(response => {
            const $ = cheerio.load(response.data)
            let scrapedWebPageJson

            contentForParsing = $("script").get().children[0].data                   
            scrapedWebPageJson = JSON.parse(contentForParsing)

            return scrapedWebPageJson
        })
}

scrapWebPage还包含一些解析来返回我想要的一些JSON数据 - 它正确解析(测试过)并返回Promise。

但是我想在多个域上调用此方法,因此我创建了getProductDataFromManyDomains

const getProductDataFromManyDomains = (productNum) => {
    let prodData = {
        reviews: []
    }

    const appCountries = [
        {countryCode: 'nl'}, 
        {countryCode: 'pl'},
        {countryCode: 'de'}
    ]

    appCountries.forEach(async countryApp => {
        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)
    })

    return prodData
}

现在我在填充之前收到prodData ...而我希望收到实际数据(填充prodData)。

我不确定在填充之前我应该​​如何构造这个getProductDataFromManyDomains方法来实际返回数据而不是prodData。那可能吗?或者这里有什么好的模式来处理这样的事情?

1 个答案:

答案 0 :(得分:2)

使用<?php if(isset($_POST['name']) && isset($_POST['html']) && isset($_POST['pubblicato'])){ $oggetto = $_POST['oggetto']; $html = $_POST['html']; $pubblicato = $_POST['pubblicato']; $oggetto = addslashes(htmlentities($oggetto)); $html = addslashes(htmlentities($html)); echo "Oggetto: $oggetto"; echo "<br>HTML: $html"; echo "<br>Pubblicato: $pubblicato"; }else{ echo "Errore"; } ?> 循环代替for.forEach()循环将暂停等待,for循环不会。这是因为您传递给.forEach()的{​​{1}}回调将返回一个承诺,但async并非旨在对该承诺执行任何操作,因此在继续执行之前它不会等待它解决循环,但使用.forEach()进行.forEach()循环。

然后,for将需要await并将返回您的最终结果的承诺。

getProductDataFromManyDomains()

您也可以并行运行多个请求,而不是一次运行多个请求,但由于您最初尝试让代码一次执行一个,我向您展示了如何执行此操作。

如果你想并行执行它们,你只需在数组中累积promises并使用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()