2016-11-23 77 views
0

我看了一些關於這個主題的其他問題,但是在這種情況下無法包裝我的頭如何實現它。Nodejs:比較兩個異步請求的結果

我想實現:

  1. 訪問網站,並獲得內容(身體)
  2. 訪問相匹配的測試網站,並獲得內容(身體)
  3. 比較內容的第1頁
  4. 抓取鏈接
  5. 第2頁的抓取鏈接
  6. 繼續

我目前遇到的問題是我無法比較內容,因爲請求並未等待對方。 這是我的代碼現在的樣子。

require('colors'); 
var request = require('request'); 
var cheerio = require('cheerio'); 
var jsdiff = require('diff'); 
var URL = require('url-parse'); 

var PROD_START_URL = "https://www.somesite.org"; 
var MAX_PAGES_TO_VISIT = 100; 

var pagesVisited = {}; 
var numPagesVisited = 0; 
var pagesToVisit = []; 

var globalProdContent; 
var globalTestContent; 

var url = new URL(PROD_START_URL); 
var baseUrl = url.protocol + "//" + url.hostname; 

pagesToVisit.push(PROD_START_URL); 
crawl(); 

function crawl() { 
    if(numPagesVisited >= MAX_PAGES_TO_VISIT) { 
    console.log("Reached max limit of number of pages to visit."); 
    return; 
    } 
    var nextPage = pagesToVisit.pop(); 
    if (nextPage in pagesVisited) { 
    // We've already visited this page, so repeat the crawl 
    crawl(); 
    } else { 
    // New page we haven't visited 
    visitPage(nextPage, crawl); 
    } 
} 

function visitPage(url, callback) { 
    // Add page to our set 
    pagesVisited[url] = true; 
    numPagesVisited++; 

    // Make the request 
    console.log("Visiting page " + url); 
    request(url, function(error, response, body) { 
    // Check status code (200 is HTTP OK) 
    console.log("Status code: " + response.statusCode); 
    if(response.statusCode !== 200) { 
     callback(); 
     return; 
    } 
    // Parse the document body 
    var $ = cheerio.load(body); 
    globalProdContent = $("#wrapper").text(); 

    // Build new URL for test site 
    var testURL = url.replace("https://www.somesite.org", "http://matching.testsite"); 

    // Scrape test site 
    scrapeTestContent(testURL); 


    collectInternalLinks($); 
    callback(); 
    }); 
} 

function collectInternalLinks($) { 
    var relativeLinks = []; 
    relativeLinks = $("a[href]"); 

    console.log("Found " + relativeLinks.length + " relative links on page"); 
    relativeLinks.each(function() { 
     pagesToVisit.push(baseUrl + "/" + $(this).attr('href')); 
    }); 
} 

function scrapeTestContent(testURL) { 
    console.log("Visiting matching testpage " + testURL); 
    request(testURL, function(error, response, body) { 
     console.log("Status code: " + response.statusCode); 
     if(response.statusCode !== 200) { 
      callback(); 
     return; 
     } 

     var $ = cheerio.load(body); 
     globalTestContent = $("#wrapper").text(); 
     console.log(globalTestContent); 

    }); 
} 

有沒有更簡單的方法來做到這一點,還是我完全脫離軌道?

回答

0

這可以通過兩種方式來完成: 1.添加回調scrapeTestContent

function scrapeTestContent(testURL, cb) { 
     ... 
     request(testURL, function(error, response, body) { 
      cb(); 
     }); 

    In visitPage, 

    function visitPage(url, callback) { 
     ... 
     scrapeTestContent(testURL,() => collectInternalLinks($)); 
    } 
  • 使用ES6承諾。在scrapeTestContent()返回new Promise((resolve, reject) => {}。然後在visitPage,使用以下構造:scrapeTestContent(testUrl).then(() => collectInternalLinks($))