我有这段代码,我要在注释EXECUTION完成后等待Promise.all
,然后继续执行其他任务。请注意,我使用的是PromiseJS,而不是BlueBird。我搜索了有关等待/异步的问题,但没有一个对我有用。如果您觉得代码很长,很抱歉,因为我想公开所有内容。也许不这样做,你们中的一些人可能会说“也许某个地方有错误”。
// ================ load the lib ================
const curl = require("curl");
const jsdom = require('jsdom');
const cheerio = require('cheerio');
const Promise = require("promise");
// ================ declare global constants ================
const domain = "https://www.bankmega.com";
var url = domain + "/ajax.promolainnya.php";
const categories = [1, 2, 3, 4, 5, 6]; // hard-code subcat but later can be changed
// simply by loading the main page, then get all the subcat
// and convert to an appropriate integer array representing the
// categories
var visited = new Set(); // store visited links (not to scrap an item twice)
// ================ declare methods ================
function getItemLinksOfCat(url, subcat) {
const subCatURL = url + "?product=&subcat=" + subcat;
curl.get(subCatURL, null, (err, resp, body) => {
const {JSDOM} = jsdom;
const dom = new JSDOM(body);
const $ = (require("jquery"))(dom.window);
var tds = $("table[class=tablepaging] tr").children();
var maxPage = getMaxPage(tds, $);
var itemLinks = getItemLinks(maxPage, $, subcat);
// itemLinks.forEach(itemLink => {
// if (!visited.has(itemLink)) {
// visited.add(itemLink);
// scrapItem(itemLink);
// }
// });
Promise.all(itemLinks.map(function(itemLink) {
if (!visited.has(itemLink)) {
visited.add(itemLink);
scrapItem(itemLink);
}
}));
});
}
function getItemLinks(maxPage, $, subcat) {
var itemLinks = [];
var product = "";
for (var i = 1; i <= maxPage; ++i) {
var page = i;
$("#contentpromolain2").load("ajax.promolainnya.php?product="+product+"&subcat="+subcat+"&page="+page);
var lis = $("ul#promolain").children();
for (var j = 0; j < lis.length; ++j) {
var itemLink = $(lis[j]).find("a").attr("href");
itemLinks.push(itemLink);
}
}
return itemLinks;
}
function getMaxPage(tds, $) {
var maxPage = -1;
for(var i = 0; i < tds.length; ++i ){
var td = $(tds[i]);
var page = parseInt(td.text());
if (page != NaN && page > maxPage) {
maxPage = page;
}
}
return maxPage;
}
/*
Using wrapper method might be useful in the future
As we can redirect a call to an appropriate method
that can handle a specific type of item
*/
function scrapItem(itemLink) {
if(itemLink.includes("promo_detail")) {
scrapPromoDetail(itemLink);
}
}
/*
Actual method to scrap promo item
We can have other methods to scrap other types of item
*/
function scrapPromoDetail(itemLink) {
itemLink = domain + "/" + itemLink;
curl.get(itemLink, null, (err, resp, body) => {
if (resp != undefined && resp.statusCode == 200) {
var s = parseItemHTMLToString(body, itemLink);
console.log(s);
console.log("========");
}
});
}
/*
Helper function to parse item's html to string
Return a string contains item's property-value pairs
*/
function parseItemHTMLToString(html, itemLink) {
const $ = cheerio.load(html);
var promoSection = $("div#contentpromolain2");
var promoProperties = promoSection.find("div");
var dict = {};
for (var i = 0; i < promoProperties.length; ++i) {
var div = $(promoProperties[i]);
var klass = div.attr("class");
var text = div.text().trim();
if (klass !== undefined) {
if (klass === "titleinside") { // title
dict[klass] = text;
} else {
if (klass === "periode" || klass === "area" ) { // other props
var token = text.split(":");
text = token[1];
if (klass === "periode") {
token = text.split("-");
for(var j = 0; j < token.length; ++j) {
token[j] = token[j].trim();
}
dict[klass] = token.join(" - ");
} else { // area
dict[klass] = text;
}
} else if (klass === "keteranganinside") { // promo image
dict[klass] = domain + div.find("img").attr("src").trim();
} else { // other props
dict[klass] = text;
}
}
}
}
return dict;
}
// ================ EXECUTION ================
Promise.all(categories.map(function(subcat) {
getItemLinksOfCat(url, subcat)
}));
// do other tasks after Promise.all
编辑1 我已经尝试过了:
// ================ EXECUTION ================
async function ttt() {
await Promise.all(categories.map(function(subcat) {
getItemLinksOfCat(url, subcat)
}));
// do other tasks after Promise.allc
}
ttt().then( result => {
console.log("Finish");
});
但是没有用。
这是输出的一部分:
Finish
{ titleinside: 'Mega Cellular - Free Tempered Glass',
area: ' Pontianak',
periode: '20 Juli 2018 - 18 Oktober 2018',
keteranganinside:
'https://www.bankmega.com/files/images/00-landing-page-MEGACELL.jpg' }
========
EDIT 2 您好,HoldOffHunder,这是什么意思?
// ================ EXECUTION ================
async function test() {
await Promise.all(categories.map(function(subcat) {
getItemLinksOfCat(url, subcat)
}));
// do other tasks after Promise.allc
console.log("???");
}
test();
它也打印出“ ???”在运行之前。
答案 0 :(得分:1)
Promise.all(...)
必须采用 Promise-type 变量的数组。并且应该紧跟.then(() => { //success code results}
,但我没有看到。
签出:Mozilla Developer Network: Promise.all()
一个承诺看起来像...
var promise3 = new Promise(function(resolve, reject) {...});
您将像使用Promise.all()
一样
var promisearray = [
//somepromiseshere
];
Promise.all(
promisearray
).then(() => {
console.log("Promise all finished.");
}, () => {
console.log("Promise all failed.");
});
或者,另一个使用await()的方法-
由于Promise.all()是异步的,因此也可以使用await
,就像这样...
await Promise.all(promisearray);
签出:Mozilla Developer Network: Async Function
第一种方法比较可取,因为它包含catch块,但是没有理由不能以各种方式组合这些块。
答案 1 :(得分:0)
我了解您是堆栈溢出的新手,并且可能使用javascript和promises。这是使用Promise
和Promise.all()
var people = ["James", "John", "Aaron", "Lane", "Josh", "Isaac"];
let cars = ["Subaru", "Ford", "Chevrolet", "Mercedes", "Toyota"];
let getPeople = () => {
let promise = new Promise((resolve, reject) => {
if (people)
resolve(people);
else
reject("People does not exist");
})
return promise;
}
let getCars = () => {
let promise = new Promise((resolve, reject) => {
if (cars)
resolve(cars);
else
reject("cars does not exist");
});
return promise;
}
let promiseArr = [getPeople(), getCars()]
Promise.all(promiseArr)
.then((resp) => {
console.log(resp[0])
console.log(resp[1])
})
.catch((err) => {
console.log(err)
})