我将尽我所能清楚地解释这一点,但这让我很困惑,所以请耐心等待。
对于这个项目,我将Node.js与Axios和Cheerio模块结合使用。
我正在尝试从网上商店(类似于Amazon / eBay)获取HTML数据,并将产品信息存储在字典中。我设法存储了大多数东西(标题,价格,图像),但是产品说明在另一个页面上。要对此页面进行请求,我使用的是从第一个请求中获得的URL,因此它们是嵌套的。
第一部分是通过以下请求完成的:
let request = axios.get(url)
.then(res => {
// This gets the HTML for every product
getProducts(res.data);
console.log("Got products in HTML");
})
.then(res => {
// This parses the product HTML into a dictionary of product items
parseProducts(productsHTML);
console.log("Generated dictionary with all the products");
})
.then(res => {
// This loops through the products to fetch and add the description
updateProducts(products);
})
.catch(e => {
console.log(e);
})
我还将提供创建产品对象的方式,因为这可能会澄清我认为出现问题的功能。
function parseProducts(html) {
for (item in productsHTML) {
// Store the data from the first request
const $ = cheerio.load(productsHTML[item]);
let product = {};
let mpUrl = $("a").attr("href");
product["title"] = $("a").attr("title");
product["mpUrl"] = mpUrl;
product["imgUrl"] = $("img").attr("src");
let priceText = $("span.subtext").text().split("\xa0")[1].replace(",", ".");
product["price"] = parseFloat(priceText);
products.push(product);
}
}
问题出在updateProducts函数中。如果以后我用console.log字典,则不添加描述。我认为这是因为控制台将在添加描述之前记录日志。这是更新功能:
function updateProducts(prodDict) {
for (i in prodDict) {
let request2 = axios.get(prodDict[i]["mpUrl"])
.then(res => {
const $ = cheerio.load(res.data);
description = $("div.description p").text();
prodDict[i]["descr"] = description;
// If I console.log the product here, the description is included
})
}
// If I console.log the product here, the description is NOT included
}
我不知道要尝试什么,我想可以通过async / await之类的方法或在代码上设置超时来解决。有人可以帮助我正确更新产品并添加产品说明吗?提前非常感谢您。
答案 0 :(得分:1)
要使用async / await重构它,可以这样做:
async function fetchAndUpdateProducts() => {
try {
const response = await axios.get(url);
getProducts(response.data);
console.log("Got products in HTML");
parseProducts(productsHTML);
console.log("Generated dictionary with all the products");
await updateProducts(products);
} catch(e) {
console.log(e);
}
}
fetchAndUpdateProducts().then(() => console.log('Done'));
和
async function updateProducts(prodDict) {
for (i in prodDict) {
const response = await axios.get(prodDict[i]["mpUrl"]);
const $ = cheerio.load(response.data);
description = $("div.description p").text();
prodDict[i]["descr"] = description;
}
}
除非已解决updateProducts返回的承诺,否则不会继续结束对fetchAndUpdateProducts的调用。