我正在使用Request-Promise和cheerio来抓取一些网站数据,基本上我试图实现以下目标:
{link: "some url", items: [{item},{item}]}, {link: "some url", items: [{item},{item}]}, {link: "some url", items: [{item},{item}]}
第6步是我遇到问题的地方,我不知道怎么做,如果没有在for循环中嵌入promise,根据我的代码,然后开始变得讨厌。我能指出正确的方向吗?
这是我目前的代码:
let orderArray = []; rp.post(login) .then(function(res1){ // Login & Set Cookies cookieJar = res1.headers['set-cookie']; return rp(getOpenOrders); }) .then(function($){ // Get Some Info from getOpenOrders orderArray.push({info}); return rp(getShippedOrders); }) .then(function($){ // Get Some Info from getShippedOrders orderArray.push({info}); return orderArray; }) .then(function($){ // Loop through each object in the orderArray for (i = 0,; i < orderArray.length; i++){ rp(orderArray[I].link) .then(function($){ //Get length of items on page let itemsOnPage = $('tbody tr').length; //Get some more details for each object for (j = 0,; j < items.length; j++) { let moreinfo = {…}; orderArray.items.push(moreinfo); } } } return orderArray; }) .then(function($){ // Log finished Array console.log(orderArray); }) .catch(function(err){ console.log(err); }) };
答案 0 :(得分:2)
最简单,最干净的方法是使用async/await
。该代码不会并行运行(除非我们等待Promise.all
)
.then(async() => {
// Loop through each object in the orderArray
for(let i = 0; i < orderArray.length; i++) {
// Some may argue no await inside loop...
// We wait for rp to resolve, it looks like
// synchronous code so it's easy to understand
const $ = await rp(orderArray[i].link);
let items = $('tbody tr');
for(const item of items) {
let moreinfo = {};
orderArray[i].items.push(moreinfo);
}
}
return orderArray;
})
您还可以使用Promise.all并行发送所有请求,并在结果完成后处理结果。
.then(() => {
// Loop through each object in the orderArray
const requests = [];
for(const order of orderArray) {
// Push each promise
requests.push(
rp(order.link)
);
}
// This will resolve when every request finishes
// If one fails, it will reject, going to `.catch`
return Promise.all(requests);
})
.then(results => {
// Results is an array containing each individual request result.
results.forEach(($, i) => {
//Get length of items on page
let items = $('tbody tr');
//Get some more details for each object
for(const item of items) {
let moreinfo = {};
orderArray[i].items.push(moreinfo);
}
})
return orderArray;
});
我认为rp
会解析一个cheerio对象,如果它没有让我知道。
我无法对其进行测试,因为我没有完整的代码,但它应该有效。