Promise返回空列表

时间:2017-03-29 10:25:10

标签: javascript promise bluebird cheerio

我编写了一个函数,通过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()

1 个答案:

答案 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);
    });
};