2017-03-29 14 views
0

ウェブスクレイピングでハイパーリンクアンカーのリストを取得する関数を記述しました。プロミスが空のリストを返します

これらのアンカーをすべてオブジェクト配列にプッシュします。この配列は、後でJson文字列にシリアル化されます。

Api.GetCourseSubmenuUrlの方法とApi.FilterSubmenuContentListの両方が約束を返します。

しかし、次のコードは、配列が.each() cheerio関数で埋められるのを待つことなく実行し続けます。なぜこれが起こるのですか?

cheerioの各メソッドは同期しています。

私のコードは、パッケージを使用します

コード:

Connection.prototype.FillCourseWithSubmenuContent = function(course){ 
    var self = this; //This class 
    var submenuItems = []; 
    return new BPromise(function(resolve, reject){ 
     return Api.GetCourseSubmenuUrl(ApiConnection.authToken).then(function(response){ 
     return 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')}); 
      }); 
      resolve(); 
     }); 
     }).then(function(){ 
     console.log(submenuItems); 
     return Api.FilterSubmenuContentList(ApiConnection.authToken, submenuItems); 
     }); 
    }).catch(function(error){ 
     return reject(error); 
    }); 
}; 
+0

が([ 'Promise'コンストラクタアンチパターン]を避けますhttp://stackoverflow.com/q/23803743/1048572?What-is-the-promise-construction-反パターン - と - 回避する方法 - それ)! – Bergi

+0

呼び出している 'reject'関数はスコープ内でさえありません。 – Bergi

+0

@Bergi私は反パターンが私のコードにどのように訴えるのかを本当に把握していませんか?どこが間違っていますか?それは約束の中で約束をすることですか?あなたは最初の拒否について話していますか? – Dragon54

答えて

1

この問題は、@ Bergi氏が指摘したPromise constructor antipatternを考慮して修正されました。

リクエストライブラリには約束のサポートがないので、私はまだそれを(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); 
    }); 
}; 
+1

+1、これは私が言ったことです。私は '解決(身体) 'を行う限りでさえ、例外を自動的に捕まえる' then'ハンドラに 'cheerio'を入れました – Bergi

関連する問題