在promise中等待功能

时间:2019-03-20 14:55:55

标签: javascript node.js cheerio

我想在异步函数中创建一个新的Promise。 在此Promise中,我想调用另一个异步函数,该函数将调用一些异步内容(从网页中删除HTML)。

这是我的代码:

 async extractProductUrlFromHTML(html) {
    const products = html(`h2.product-name`).toArray();
    let extracted = [];
    let promises = [];
    for (let index = 0; index < products.length; index++) {
        const element = products[index];
        let productUrl = element.children[0].attribs.href;
        const productProm = new Promise(async (resolve, reject) => {
            try {               
                console.log("process");
                const product = await this.getProductInfos(productUrl);
                console.log("resolving")
                resolve(product);
            } catch (error) {
                reject(error)
            }

        })
        promises.push(productProm);

    }
    Promise.all(promises).then((prods) => {
        console.log("promises ok", prods)
        extracted.push(prods);
        return (extracted);
    })
}

这是函数的调用方式:

async scrapAllProducts({ request, response }) {
    let extractedProducts = []

    //get the html page
    const html = await AxiosService.getHTML('http://www.ubagcollection.com/fr/ubag.html?limit=36')
    const $ = cheerio.load(html);

    let pagesToScrap = await this.extractPagination($);
    pagesToScrap.push(`http://www.ubagcollection.com/fr/ubag.html?limit=36`)

    for (let index = 0; index < pagesToScrap.length; index++) {
        const url = pagesToScrap[index];
        let html = await AxiosService.getHTML(url);
        const $ = cheerio.load(html);
        console.log("start extraction")
        const products = await this.extractProductUrlFromHTML($);
        console.log('product extracted from page :' + index)
        extractedProducts.push(products);
    }
    console.log("all is extracted", extractedProducts)
    ... bla bla bla

我的问题是,在我所有的诺言被创建的那一刻,我可以在程序完成工作之前看到“从页面中提取的产品:...”。

这是我运行脚本时可以看到的顺序:

  

开始提取   处理   处理   处理   处理   处理   处理   处理   处理   处理   处理   处理   处理   处理   处理   处理   处理   处理   处理   处理   处理   处理   处理   处理   处理   处理   处理   处理   处理   处理   处理   处理   处理   处理   处理   处理   处理   从第1页提取的产品

每次创建承诺时,我都会记录“过程”,并且当我的异步功能完成她的工作时,我应该看到“正在解决”日志,这不是这种情况。

2 个答案:

答案 0 :(得分:2)

我认为您可以稍微兑现诺言。您无需将getProductInfos包装在promise中。您await正在使用它,因此我假设它返回了一个承诺。无需等待一个承诺,只需将其包装在另一个承诺中并加以解决即可。

也许更像是:

async extractProductUrlFromHTML(html) {
  try {
    const products = html(`h2.product-name`).toArray() || [];
    let extracted = [];
    let promises = products.map(element => {
      let productUrl = element.children[0].attribs.href;
      return this.getProductInfos(productUrl); // assuming getProductInfos returns a promise
    });

    const results = await Promise.all(promises); // need to await the Promise.all
    extracted.push(results); // Do you really want to push the array of results into another array? You'll have [[productInfo1, productInfo2, ...]]
    return extracted;
  } catch (e) {
    console.error(e);
  }
}

答案 1 :(得分:0)

好,我解决了我的问题。 我删除了一个代码示例,也许对某人有用。

    let extracted = [];
    let promises = [];
    for (let index = 0; index < products.length; index++) {
        const element = products[index];
        let productUrl = element.children[0].attribs.href;
        const productProm = new Promise(async (resolve, reject) => {
            try {
                await utils.timeout(utils.getRandomInt(1000,4000))
                const product = await this.getProductInfos(productUrl);
                resolve(product);
            } catch (error) {
                reject(error)
            }

        })
        promises.push(productProm);

    }
    let prods = await Promise.all(promises)
    extracted.push(prods);