nodejs函数返回undefined

时间:2015-02-24 09:47:31

标签: javascript node.js function asynchronous

背景

我已经建立了一个小型网站来进行小费比赛。我正在使用chartjs来绘制garphs。我已经创建了一个函数(createCjsDonutDataWinnerPickData)来将图表的数据格式化为适合chartjs的格式。

问题

由于某种原因,函数(createCjsDonutDataWinnerPickData)返回undefined。我认为这是由于在函数处理完毕之前返回“返回”。

我在两个地方调用该函数。第一个是在呈现页面之前的测试,第二个是在呈现页面时的测试。

从页面渲染功能中提取

Point.findOne({user:req.user.id, competition:comp.id, fixture:fixture.id}).exec(function (err, points){
        if (err) {console.log('ERR: fixtures pick page on COMP lookup')}
        else {
            console.log('TEST FUNCTION');
            console.log(createCjsDonutDataWinnerPickData(fixture._id,comp._id,createIdLookup(teams)));
            res.render('fixturePick.ejs', {
                user : req.user, // get the user out of session and pass to template
                fixture: fixture,
                pick: pick,
                teams: createIdLookup(teams),
                draw: draw,
                round: round,
                competition: comp,
                points: points,
                gWinnerPickGraph: JSON.stringify( createCjsDonutDataWinnerPickData(fixture._id,comp._id,createIdLookup(teams)) ),                                   
                successMsg: req.flash('successMsg'),
                dangerMsg: req.flash('dangerMsg'),
                warningMsg: req.flash('warningMsg')
            });
        }
    });

函数createCjsDonutDataWinnerPickData

function createCjsDonutDataWinnerPickData(fixtureID,competitionID,teamLookup){
    var Statistic = require('../app/models/statistic');
    var Fixture = require('../app/models/fixture');
    var async = require('async');

    try {
        async.waterfall([
            function(cb_ReturnData){
                var chartData =[];
                Statistic.findOne({fixture:fixtureID, competition:competitionID,type:'winnerPickNumber'}).populate('fixture').exec(function (err,statData){
                    if (err) {console.log('ERROR in preparing data for graph');throw (err)}
                    else {

                        async.each(statData.data, function(dataPoint,cb_PrepData){
                            var sliceData = {};
                            if (statData.fixture.homeTeam._id == dataPoint.teamID){
                                //console.log('Found data for home team')
                                sliceData = {value: dataPoint.number, color:"rgba(151,187,205,0.5)", highlight: "rgba(151,187,205,0.75)", label:teamLookup[dataPoint.teamID].name };
                            }
                            else
                            {
                                //console.log('Found data for away team')
                                sliceData = {value: dataPoint.number, color:"rgba(220,220,220,0.5)", highlight: "rgba(220,220,220,0.75)", label:teamLookup[dataPoint.teamID].name };
                            }
                            //console.log('Pusihgin slice data to data')
                            chartData.push(sliceData);
                            cb_PrepData();
                        }, function(err){
                            if (err) {
                                console.log('ERROR in creating data for WinnerPickGraph');
                                cb_ReturnData(err);
                            }
                            else {
                                //console.log('CHART DATA IN INNER ASYNC');
                                //console.log(chartData);
                                cb_ReturnData(null, chartData);
                            }
                        });

                    }
                });


            }
            ],function(err,chartData){
                if (err) {console.log('ERROR in preparing return data')}
                else {
                    console.log('HERE IS THE FINAL RETURN');
                    console.log(chartData);
                    return (chartData);
                }
            });
     }
    catch (err){
        //probably end up here because there is no points History Data
        console.log('threw erro returning undefined');
        return undefined;
    }
}

控制台输出

GET /fixturePick?competition=542a5ffa736e3e35532f2d24&fixture=542c9ae12367c9209a739150 302 5.532 ms - 58
PATH: /fixturePick?competition=542a5ffa736e3e35532f2d24&fixture=542c9ae12367c9209a739150
GET / 200 11.291 ms - 1515
GET /images/grassBackground.jpg 200 5.533 ms - 145369
POST /login 302 459.431 ms - 228
TEST FUNCTION
undefined
GET /fixturePick?competition=542a5ffa736e3e35532f2d24&fixture=542c9ae12367c9209a739150 200 1609.303 ms - 4984
GET /images/team/logo/sm/53fc6399b918a6b661d423b4.png 200 2.720 ms - 15747
HERE IS THE FINAL RETURN
[ { value: 1,
    color: 'rgba(220,220,220,0.5)',
    highlight: 'rgba(220,220,220,0.75)',
    label: 'Melbourne Victory' },
  { value: 2,
    color: 'rgba(220,220,220,0.5)',
    highlight: 'rgba(220,220,220,0.75)',
    label: 'Western Sydney Wanderers' } ]
HERE IS THE FINAL RETURN
[ { value: 1,
    color: 'rgba(220,220,220,0.5)',
    highlight: 'rgba(220,220,220,0.75)',
    label: 'Melbourne Victory' },
  { value: 2,
    color: 'rgba(220,220,220,0.5)',
    highlight: 'rgba(220,220,220,0.75)',
    label: 'Western Sydney Wanderers' } ]
GET /images/team/logo/sm/53fc6399b918a6b661d423b5.png 200 2.368 ms - 13144
GET /images/none.png 200 1.857 ms - 195

我可能用async.foreach和async.waterfall过度复杂了这一点但是我的想法已经用完了为什么函数不断返回未定义。

1 个答案:

答案 0 :(得分:0)

createCjsDonutDataWinnerPickData将始终返回undefined,因为它是异步的。要获得结果处理,您应该传递回调或返回一个承诺。

以下是这些方法的一些示例:

// callback
createCjsDonutDataWinnerPickData(fixture._id,comp._id,createIdLookup(teams), function(err, data) {
    // do something with err and data now
});

// promise (es6-promise)
createCjsDonutDataWinnerPickData(fixture._id,comp._id,createIdLookup(teams)).then(function(data) {
    // got some data, do something
}).catch(function(err) {
    // deal with the error
});

es6-promise可以采用后期方法。 bluebird效果也很好。