两个异步模块函数异步工作

Two async module functions work asynchronously

本文关键字:异步 模块 工作 函数 两个      更新时间:2023-09-26

我试图废弃数千页。所以我使用了async.timesSeries和async.waterfall。每个函数都能很好地同步工作,但它们不能一起工作。我能做什么?

逻辑很简单。

  1. 因为我想刮页是"http://udb.kr/local/category/390101?page="1~1167,异步时间系列循环1~1167

  2. 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)
});

要在每次时序迭代中使用瀑布式调用,就需要从瀑布式调用的完成回调中调用时序done回调。现在,您早在那之前就调用了它,这意味着时间序列不会等待瀑布完成。

你可以通过改变这个来做到这一点:

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

到此:

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

同样奇怪的是,您有一个硬编码的for循环限制m < 150,而不是使用内容的实际长度。您可以很容易地用完内容的末尾,并可能导致问题。

而且,您的错误处理可能也不会很好地工作。如果在异步request()回调中使用throw,则不会有任何结果。您需要更好的错误处理,例如调用callback(error)将错误传递给async.waterfall()

您还可能希望在try/catch中围绕所有DOM遍历,这样,如果您在其中抛出任何异常,您可以自己捕获它们,分析它们,然后修复代码。

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