使用回调和导出结果连接JSON对象

时间:2014-07-29 18:15:25

标签: javascript json node.js jsdom

完全披露,我是NodeJS和Express的新手。但是,下面的代码可以运行并进行测试,因此应该是一个很好的起点。

我正在尝试在同一个网站上抓取各种页面,从每个页面将数据拉入一个大的JSON对象。然后我想将所有这些JSON对象合并为一个甚至更大的JSON对象,然后我想导出它以便我可以在另一个文件中调用它。

这是我的dataFetch.js

var request = require('request'),
jsdom = require('jsdom');

var PlayerData = [];

var QBFunction = jsdom.env({
    url: 'http://www.fantasypros.com/nfl/projections/qb.php',
    scripts: ["http://code.jquery.com/jquery.js"],
    done: function (errors, window) {
        var $ = window.$;
        var table = $("tbody:gt(0)").hide();
        var QBObject = [];
        table.find("tr").each(function (i, el) {
            var $tds = $(this).find('td');
            QBObject.push({
                'position': 'QB',
                'name': $tds.eq(0).text(),
                'passing_attempts': $tds.eq(1).text(),
                'completions': $tds.eq(2).text(),
                'passing_yards': $tds.eq(3).text(),
                'passing_tds': $tds.eq(4).text(),
                'interceptions': $tds.eq(5).text(),
                'rushing_attempts': $tds.eq(6).text(),
                'rushing_yards': $tds.eq(7).text(),
                'rushing_tds': $tds.eq(8).text(),
                'fumbles_lost': $tds.eq(9).text(),
                'standard_projection': $tds.eq(10).text()
            });
        });
    }
})

exports.PlayerData = PlayerData;

上面,QBObject是我在抓取网页时创建的初始JSON对象的示例。我的想法是我为每个位置做这个,所以想象我有5个不同位置的相同代码(为了简洁,我把它留下了)。 QBObject正在完美创建。

我的问题是,我何时以及如何将QBObjectPlayerObject结合起来,请记住我还必须将其与RBObject等结合起来...... ?我很困惑因为QBObject是在回调中创建的,而且我是异步编程的新手。我尝试连接回调中的JSON对象并将其打印到控制台,但它是空的(我假设因为控制台日志是在创建JSON对象之前执行的)。

最后,如果一切按计划进行,并且PlayerObject JSON按预期创建,那么将是一个简单的

var dataFetch = require('./dataFetch');
var PlayerData = dataFetch.PlayerObject;

是否足以将该数据带入另一个javascript文件?感谢任何人的帮助,任何事情都值得赞赏。

1 个答案:

答案 0 :(得分:1)

您可能会发现这些讨论很有用:
How do JavaScript closures work?
Idiomatic way to wait for multiple callbacks in Node.js

解决此问题的初步尝试(我很快就会重构)可能看起来像:

var request = require('request');
var jsdom = require('jsdom');

function fetchPlayerData(done) {
    var playerObject;

    function gotData() {
       if ( playerObject.RBObject && playerObject.QBObject ) {
          //if all went well, we should have data for all positions
          done(playerObject);
       }
    }

    function qbReady(errors, window) {
        //existing code for scraping except...
        playerObject.QBObject = {
            position: 'qb',
            name: $tds.eq(0).text()
        }; 
        //we write to the player object instead of a local
        gotData();
    } 

    function rbReady(errors, window) {
        //same for other positions
        playerObject.RBObject = {position: 'rb'}; 
        gotData();   
    }

    jsdom.env({
        url: 'http://www.fantasypros.com/nfl/projections/qb.php',
        scripts: ["http://code.jquery.com/jquery.js"],
        done: qbReady 
    });

    jsdom.env({
        url: 'http://www.fantasypros.com/nfl/projections/rb.php',
        scripts: ["http://code.jquery.com/jquery.js"],
        done: rbReady 
    });
}

module.exports = {
    fecthPlayerData: fetchPlayerData
};

然后用法就像:

var fetch = require('./dataFetch');

fetch.fetchPlayerData(function(data){
    console.log(data.QBObject);
});