node.js promise.then()在没有all()实现的情况下获得执行

时间:2017-10-23 11:18:45

标签: javascript node.js asynchronous promise web-crawler

我在 node.js 中编写抓取工具时遇到了问题。问题是,then()的promise会在调用后执行,但不会在promise数组all()返回实现时执行。

我一直在寻找并试图找到原因,但似乎以前没有人遇到这个问题。

var http = require('https');
var cheerio = require('cheerio');
var Promise = require('bluebird');
var url = 'https://developer.teamwork.com/';


function filterData(html) {
    var $ = cheerio.load(html);
    // console.log(html);
    // var data = {
    //     title: title,
    //     APIs: [{
    //         apiTitle: apiTitle,
    //         type: type,
    //         apiUrl: apiUrl,
    //         description: description,
    //         req: {
    //             description: description,
    //             content: {}
    //         },
    //         res: {
    //             description: description,
    //             content: {}
    //         }
    //     }]
    // };
    var title = $('.api--main').find('h2').text();
    console.log('|' + title + '|');

}


function filterModules(html) {
    var $ = cheerio.load(html);
    var modules = $('.api--main').find('.lev1');
    // [{
    //     moduleTitle: '',
    //     moduleURL: ''
    // }]
    var modulesData = [];
    var module = '', moduleTitle = '', Url = '';
    modules.each(function (item) {
        module = $(this).find('a');
        moduleTitle = module.text();
        Url = module.attr('href');
        if (!Url.match('//')){
            moduleUrl = url + Url;
        } else {
            moduleUrl = Url;
        }
        modulesData.push({
            moduleTitle: moduleTitle,
            moduleUrl: moduleUrl
        });
    });

    return modulesData;
}

function printModuleInfo(data) {
    var moduleTitle;
    var moduleUrl;
    var printResults = '';
    data.forEach(function (item) {
        moduleTitle = item.moduleTitle;
        moduleUrl = item.moduleUrl;
        printResults = printResults + '<' + moduleTitle + '>\n' + '  URL: ' + moduleUrl + '\n';
    });
    return printResults;
}

function getContents(url,title) {
    return new Promise(function(resolve, reject) {
        http.get(url, function(res) {
            console.log('crawling:'+url);
            var html = '';

            res.on('data', function(data) {
                html += data;
            });

            res.on('end', function() {
                resolve({
                    title: title,
                    html: html
                });
            });
        }).on('error', function(e) {
            reject(e);
        });

    });
}



var allOriContents = [];

http.get(url, function (res) {
    var html = '';
    res.on('data', function (data) {
        html += data;
    });

    res.on('end', function () {
        // console.log(html);
       var modulesData = filterModules(html);
        modulesData.forEach(function (item) {
            // console.log(item.moduleTitle);
            if (!(item.moduleTitle === 'Introduction')) {
                allOriContents.push(getContents(item.moduleUrl,item.moduleTitle));
                // console.log(allOriContents[0]);
            } else {}
        });
    });
}).on('error', function () {
    console.log('There are errors when getting urls.');
});
// setTimeout(function () {
    Promise
        .all(allOriContents)
        .then(function (obj) {
            console.log(obj.length);
            var modulesData = [];
            var module;
            var moduleData;
            obj.forEach(function (item) {
                console.log(item.title);
                module = filterData(item.html);
                moduleData = {
                    title: item.title,
                    data: module
                };
                modulesData.push(module);
            });
            modulesData.sort(function(a, b) {
                return a.title < b.title;
            });
        })
        .catch(function (err) {
            console.log(err);
        });
// }, 120000);

任何帮助将不胜感激。谢谢。

1 个答案:

答案 0 :(得分:0)

那是因为你的http.get也是一个异步调用,当执行Promise.all(allOriContents)时,allOriContents可能是空的。

将您的承诺代码移至res.end

file