2014-05-03 59 views
0

我正在使用cheerio和節點來做網頁抓取。我認爲使用promise可以更容易地處理異步代碼,這是個好主意。所以,試圖連鎖承諾,但不能使其工作。我在這裏粘貼我的代碼,這樣有人可以幫我弄清楚我究竟做了什麼錯誤。Web抓取和節點承諾

http.createServer(function(req, res){ 
    res.writeHead(200, {"Content-Type": "application/json"}) 
    loadPage().then(parseLoadedData); 

}).listen(3000, function(error){ 
    console.log(error); 
}); 


function fetchMainPage(){ 
    var deferred = q.defer(); 
    http.get('http://www.google.com?q=node', function(response){ 
     var responseString = ''; 
     response.on('data', function(data){ 
     responseString += data.toString('utf8'); 
     }); 
     response.on('error', function(error){ 
     deferred.reject(error); 
     }); 
     response.on('end', function(){ 
     deferred.resolve(responseString); 
     }); 
    }); 
    return deferred.promise; 
} 


function parseMainContent(responseString){ 
    var deferred = q.defer(); 
    var $ = cheerio.load(responseString); 
    var rightCol = $('#right-col'); 
    var children = rightCol.children(); 
    var keys = Object.keys(children); 
    var results = []; 
    keys.forEach(function(key){ 
    var div = children[key]; 
    div.children.forEach(function(aChild){ 
     if(aChild.name == 'h3' && aChild.children[0].data == "Some title"){ 
     lis = aChild.next.children; 
     var results = lis.map(function(li){ 
      var anchor = $(li).find('a'); 
      if(anchor != undefined && anchor.attr('href') != undefined) 
      return [anchor.text(), anchor.attr('href')] 
     }); 
     results = results.filter(function(result){ 
      return result != undefined; 
     }); 
     deferred.resolve(results); 
     } 
    }); 
    }); 
    return deferred.promise; 
} 



var loadPage = function(){ 
return fetchMainPage().then(function(data){ 
    return data; 
    }) 
}, 
parseLoadedData = function(data){ 
    return parseMainContent(data).then(function(results){ 
    console.log(results); 
    }); 
} 

這裏的問題是我無法讓我的parseLoadedData被調用。響應從服務器獲取,但第二個鏈接似乎沒有工作。我想先謝謝大家幫助我。

注:我使用的網址是不同的,所以解析函數只處理該特定網址。

+0

什麼是'parseMainContent'函數應該完成的?在循環中嘗試'deferred.resolve()'絕對不是個好主意...... – Bergi

回答

0

你並不真的需要loadPage功能,因爲fetchMainPage已經返回一個承諾所以這應該工作:

var loadPage = function(){ 
return fetchMainPage(); 
} 

要鏈承諾每then回調應該返回另一個承諾,你返回data。 例如:

var loadPage = function(){ 
    var deferred = q.defer(); 
    fetchMainPage().then(function(data){ 
    return someOtherPromise(data); 
    }).then(function(someOtherData) { 
    return myThirdPromise(someOtherData); 
    }).then(function(myThirdData) { 
    return deferred.resolve(myThirdData); 
    }); 
} 

// IS THE SAME AS 

var loadPage2 = function(){ 
    return fetchMainPage().then(function(data){ 
    return someOtherPromise(data); 
    }).then(function(someOtherData) { 
    return myThirdPromise(someOtherData); 
    }); 
}