我编写了一个函数,通过webscraping获取超链接锚点列表。
我想将所有这些锚点推送到一个对象数组,稍后将其序列化为一个Json字符串。
Dim RangeName As String
RangeName = Worksheets("Sheet1").Range("A1").value
MsgBox RangeName
ThisWorkbook.Names.Add Name:=RangeName, RefersTo:=Worksheets("Sheet1").Range("O1:AG15")
方法和Api.GetCourseSubmenuUrl
都返回承诺。
然而,以下代码在不等待Api.FilterSubmenuContentList
cheerio函数中填充数组的情况下继续运行。为什么会这样?
请注意,cheerio中的每个方法都是同步的。
我的代码使用了这些包:
代码:
.each()
答案 0 :(得分:1)
@Bergi指出,考虑Promise constructor antipattern
来解决问题。
由于Request库没有promise支持,我仍然需要将它包装在(Bluebird)承诺中。
请注意,promisify
图书馆也可以这样做,这会让生活变得更轻松。但是为了演示解决方案,我去了承诺包装路线。
解决方案:
Connection.prototype.FillCourseWithSubmenuContent = function(course){
var self = this; //This class
var submenuItems = [];
return Api.GetCourseSubmenuUrl(ApiConnection.authToken).then(function(response){
console.log(self.url + response.url + course.id);
return new BPromise(function(resolve, reject){
request.get({url: self.url + response.url + course.id, followRedirect: false, jar: cookiejar}, function(err,httpResponse,body){
if(err){
reject(err);
}
var cheerio = require('cheerio');
var dashboardhtml = cheerio.load(body, {
normalizeWhitespace: true,
decodeEntities: true
}
);
//Find all the links on the page
dashboardhtml('a').each(function(i, elem) {
// console.log("Object");
// console.log({"text":dashboardhtml(elem).text(), "url":dashboardhtml(elem).attr('href')});
submenuItems.push({"text":dashboardhtml(elem).text().trim(), "url":dashboardhtml(elem).attr('href')});
});
return resolve();
});
});
}).then(function(){
console.log(submenuItems);
return Api.FilterSubmenuContentList(ApiConnection.authToken, submenuItems);
});
};