2016-01-10 84 views
0

我試圖報廢數千頁。所以我使用了async.timesSeries和async.waterfall。每個功能同步工作得很好,但它們不能一起工作。我能做什麼?兩個異步模塊函數異步工作

邏輯很簡單。

  1. 因爲我想刮頁面的

但消息 「http://udb.kr/local/category/390101?page=」 1〜1167,async.timesSeries環1到1167

  • async.waterfall下腳料組件控制檯顯示我看起來像這樣

    info.NM values // just for explain, It shows me each attires of obj because I insert console.log(info.NM) for verifying. 
    info.NM values 
    info.NM values 
    info.NM values and randomly ----- page number ----- 
    ... 
    ['done', 
    'done', 
    'done', 
    'done', 
    'done', 
    ... 
    'done'] 
    info.NM values again 
    
    .../Users/Snark/Dev/job_apply/cheerio_job_app_list.js:29 
          if (tObj[m+1].children != 0) {info.nAddr = tObj[m+1].firstChild.data}else{info.nAddr = null}; 
             ^
    
    TypeError: Cannot read property 'children' of undefined 
        at /Users/Snark/Dev/job_apply/cheerio_job_app_list.js:29:17 
        at fn (/Users/Snark/node_modules/async/lib/async.js:746:34) 
        at /Users/Snark/node_modules/async/lib/async.js:1212:16 
        at /Users/Snark/node_modules/async/lib/async.js:166:37 
        at /Users/Snark/node_modules/async/lib/async.js:706:43 
        at /Users/Snark/node_modules/async/lib/async.js:167:37 
        at /Users/Snark/node_modules/async/lib/async.js:1208:30 
        at Request._callback (/Users/Snark/Dev/job_apply/cheerio_job_app_list.js:21:6) 
        at Request.self.callback (/Users/Snark/node_modules/request/request.js:198:22) 
        at emitTwo (events.js:87:13) 
    

    這是js代碼。

    var request = require("request"), 
        cheerio = require("cheerio"), 
        jsonfile = require("jsonfile"), 
        fs = require("fs"), 
        async = require("async"); 
    
    var info = {}, 
        dbArray = []; 
    
    var url = "http://udb.kr/local/category/390101?page="; 
    
    async.timesSeries(1166, function(n, next) { 
        var page = n + 1 
        async.waterfall([ 
         function(callback) { 
          request(url + page, function(error, response, html) { 
           if (error) { 
            throw error 
           }; 
           var $ = cheerio.load(html), 
            tObj = $('tbody tr td'); 
           callback(null, tObj); 
          }); 
         }, 
         function(tObj, callback) { 
    
          for (var m = 0; m < 150; m = m + 5) { 
           if (tObj[m]) { 
            info.NM = tObj[m].firstChild.children[0].data 
           } else { 
            info.NM = null 
           }; 
           if (tObj[m + 1].children != 0) { 
            info.nAddr = tObj[m + 1].firstChild.data 
           } else { 
            info.nAddr = null 
           }; 
           console.log(info.NM); 
           dbArray.push(info); 
          } 
          callback(dbArray, callback); 
         }, 
         function(dbArray, callback) { 
          fs.appendFile('./jobDB_l.json', JSON.stringify(dbArray), function (err) { 
           if (err) 
            throw err; 
          }); 
          callback(null, 'done'); 
         } 
        ], function(err, result) { 
         console.log('----- ' +page+ '-----'); 
        }); 
        next(null, 'done'); 
    }, function(err, result) { 
        console.log(result) 
    }); 
    
  • 回答

    0

    爲了得到你所使用的每個timesSeries迭代的瀑布裏面這些一起工作,你需要調用timesSeries從完成回調的瀑布呼叫done回調。現在,在這之前你就會調用它,這意味着系列不會等待瀑布完成。

    你可以通過改變這樣的:

    ], function(err, result) { 
        console.log('----- ' +page+ '-----'); 
    }); 
    next(null, 'done'); 
    

    這樣:

    ], function(err, result) { 
        console.log('----- ' +page+ '-----'); 
        next(null, 'done'); 
    }); 
    

    它也似乎很奇怪,你有m < 150硬編碼for循環限制,而不是使用內容的實際長度。您可以輕鬆地運行內容的結尾並可能導致問題。

    而且,您的錯誤處理可能也無法正常工作。如果你在異步request()回調裏面的throw,這不會去任何地方。您需要更好的錯誤處理,例如調用callback(error)將錯誤傳遞到async.waterfall()

    您可能還需要圍繞你的所有DOM走在一個try/catch所以如果你拋出任何異常那裏,你可以自己抓住他們,對它們進行分析,然後修復代碼。

    +0

    謝謝它的工作原理! –

    0
    if (tObj[m+1] && tObj[m+1].children != 0) 
    
    +0

    /Users/Snark/Dev/job_apply/cheerio_job_app_list.js:18 \t \t \t如果(誤差){擲誤差}; \t \t \t^ 錯誤:的getaddrinfo ENOTFOUND udb.kr udb.kr:80 在errnoException(dns.js:26:10) 在GetAddrInfoReqWrap.onlookup [按的onComplete](dns.js:77:26) 仍然..另一個錯誤 –

    +0

    對不起,當你問一個看似異步行爲的問題,發佈一個異常,並且當我解決這個異常時,你很難提供幫助,然後你發佈另一個與你無關的錯誤。原來的問題。這看起來像一個DNS問題或類似的東西,但如果是這樣,那麼我很確定它不會在同步模式下工作。 – Gavriel