Javascript 在承诺中等待函数

Javascript 在承诺中等待函数,javascript,node.js,cheerio,Javascript,Node.js,Cheerio,我想在异步函数中创建一个新的承诺。 在这个承诺中,我想调用另一个异步函数,它将调用一些异步内容(从网页中删除HTML) 这是我的密码: async extractProductUrlFromHTML(html) { const products = html(`h2.product-name`).toArray(); let extracted = []; let promises = []; for (let index = 0; index < pro

我想在异步函数中创建一个新的承诺。 在这个承诺中,我想调用另一个异步函数,它将调用一些异步内容(从网页中删除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 extractProductUrlFromHTML(html){
const products=html(`h2.product name`).toArray();
设提取=[];
让承诺=[];
for(让索引=0;索引{
试试{
控制台日志(“进程”);
const product=wait this.getProductInfos(productUrl);
console.log(“解析”)
解决(产品);
}捕获(错误){
拒绝(错误)
}
})
承诺、推动(productProm);
}
承诺。所有(承诺)。然后((prods)=>{
log(“承诺正常”,prods)
提取。推(prods);
返回(提取);
})
}
下面是函数的调用方式:

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
异步scrapAllProducts({request,response}){
让extractedProducts=[]
//获取html页面
const html=await AxiosService.getHTML('http://www.ubagcollection.com/fr/ubag.html?limit=36')
const$=cheerio.load(html);
让pagesToScrap=等待此操作。提取分页($);
推(`http://www.ubagcollection.com/fr/ubag.html?limit=36`)
for(让index=0;index
我的问题是,在我所有的承诺都实现的那一刻,我可以看到“从页面中提取的产品:…”,远远早于程序完成工作

以下是我运行脚本时看到的序列:

开始提取 过程 过程 过程 过程 过程 过程 过程 过程 过程 过程 过程 过程 过程 过程 过程 过程 过程 过程 过程 过程 过程 过程 过程 过程 过程 过程 过程 过程 过程 过程 过程 过程 过程 过程 过程 过程 从第页中提取的产品:1


每次创建承诺时,我都会记录“过程”,并且我应该看到“解决”当我的异步函数完成她的工作时记录日志,这里不是这样。

我认为你可以稍微清理一下你的承诺。你不需要在承诺中包装
getProductInfos
。你正在等待它,所以我假设它会返回一个承诺。没有必要等待一个承诺,只需要将它包装在另一个承诺中,然后恢复我喜欢

也许更像:

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);
  }
}
好的,我解决了我的问题。 我写了一个代码示例,也许它对某些人有用

    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);
let extracted=[];
让承诺=[];
for(让索引=0;索引{
试一试{
等待utils.timeout(utils.getRandomInt(10004000))
const product=wait this.getProductInfos(productUrl);
解决(产品);
}捕获(错误){
拒绝(错误)
}
})
承诺、推动(productProm);
}
让prods=等待承诺。全部(承诺)
提取。推(prods);

您可以在
拒绝(错误)之前添加
控制台错误(错误);
extractProductUrlFromHTML
中检查是否发生任何错误?执行此操作时,结果是什么?您可能不想这样做。您不需要将这些操作包装在承诺中。您可以将承诺中的逻辑提取到其他异步函数中。此外,如果拒绝该承诺,则没有任何错误在你等待承诺的部分等待。全部(承诺)
要捕获它,您将有一个未捕获的异常。此外,您在此处编写代码的方式是,它将按顺序处理产品,而不是并发处理,因此需要更长的时间。最好将它们映射,将产品数组转换为并发运行的承诺数组。