如何正确实现 javascript 回调

问题描述

我有一些很旧的代码。我需要调用这个函数 2 次,传递一个稍微不同的值给它。它的结果出现在下一个函数中。我从函数的第一次调用中得到结果,我没有从第二次调用中得到它。如何实施?在代码中,我用注释(//MY QUESTION)标记了我的问题。在我看来,问题的关键是如何正确实现回调

代码:

function report1(req,res,next,type) {
    if (!req.query || !req.query.name) {
        var ct = "Income statement";
        if (type == 'pieflow')
            ct = 'Pie flow chart';
        else if (type == 'barflow')
            ct = 'Bar flow chart';

        res.redirect(req.url + "?name=" +  ctx.i18n(req.session.apiToken,'cash',ct));
        return;
    }

    var pid = "reports-" + type + "-" + req.query.name;
    var vtabs,data,reportSettings;
    async.waterfall([
        function (cb1) {
            async.series([
                function(cb2) {
                    webapp.guessTab(req,{pid: pid,name:req.query.name,url:req.url},cb2);
                },function(cb2) {
                    webapp.getTabSettings(req.session.apiToken,pid,cb2);
                }
            ],function (err,results) {
                cb1(null,results[0],results[1]);
            });
        },function (vtabs_,reportSettings_,cb1) {               
            vtabs = vtabs_;
            reportSettings = reportSettings_;
            if (_.isEmpty(reportSettings) || !reportSettings.version || (reportSettings.version != reportSettingsVersion)){
                reportSettings = getDefaultSettings(req.query.name);        
                webapp.saveTabSettings(req.session.apiToken,reportSettings,function(err){
                    if (err) console.log(err);
                });
            }

            // MY QUESTION the code i need to implement
            if (reportSettings.accType == "INCOMEANDEXPENSE") {
                var splitAccType = reportSettings.accType.split('AND');
                reportSettings.accType = splitAccType[0];
                calculateGraphData(req.session.apiToken,type,cb1);
                reportSettings.accType = splitAccType[1];
                calculateGraphData(req.session.apiToken,cb1);
            }
            else {
                calculateGraphData(req.session.apiToken,cb1);
            }
        },// MY QUESTION how to get 2 values here? Only the first value comes in here
        function(data_,cb1){                
            data = data_;               
            cb1()
        },function(){                                     
            data.tabs = vtabs;
            data.pmenu = {name:req.query.name,items:[{name:webapp.ctx.i18n(req.session.apiToken,'Page settings'),id:"settings",href:"#"}]}
            data.reportSettings = reportSettings;
        
            res.render(__dirname+"/../res/views/report",data);
        }],next
    );
};  

function calculateGraphData(token,params,cb){
    var periods=categories=null;
    var accountsTree,accKeys;
    switch(type){
        case 'barflow':
            periods = getPeriods(new Date(params.startDate),new Date(params.endDate));
            categories = _.map(periods,function (p) { return (p.start.getMonth()+1)+"."+p.start.getFullYear();});
        break;
        case 'pieflow':
        break;
    }
    async.waterfall([
        function (cb1) {
            cashapi.getAllAccounts(token,cb1);
        },function (accounts,cb1) {                  
            //here not filter accounts yet 
            accKeys = _(accounts).reduce(function (memo,acc) {                 
                memo[acc._id] = {name:acc.name,_id:acc._id,parentId:acc.parentId,summ:0,type:acc.type};
                if(periods)
                    memo[acc._id].periods = _(periods).map(function (p) { return _.clone(p); });
                return memo;
            },{});     
            cashapi.getTransactionsInDateRange(token,[params.startDate,params.endDate,true,false],function(trns,cb1){         
            (function (cb) {                
            async.forEach(trns,function (tr,cb) {
                cashapi.getCmdtyPrice(token,tr.currency,{space:"ISO4217",id:params.reportCurrency},null,'safe',function(err,rate){
                    if(err && !(err.skilap && err.skilap.subject == "UnknownRate"))
                        return cb(err);
                    if (!err && rate!=0)
                        var irate = rate;
                    _.forEach(tr.splits,function(split) {
                        var acs = accKeys[split.accountId];
                        if (acs) {
                            var val = split.value*irate;
                            if (params.accType!=acs.type){
                                acs.summ  = 0;
                                val = 0;
                            }
                            if (params.accType == "INCOME")
                                val *= -1;                              
                            acs.summ += val;                                
                            if (periods) {
                                var d = tr.datePosted.valueOf();
                                _.forEach(acs.periods,function (p) {
                                    if (d > p.start.valueOf() && d <= p.end.valueOf()) {
                                        p.summ += val;
                                    }
                                });
                            }
                        }
                    });
                    cb();
                })
            },cb);
        })(safe.sure(cb1,function () {
            //collapse accounts to accLevel
            if(params.accLevel != 'All'){
                async.series([
                    function(cb2){
                        async.forEachSeries(_.keys(accKeys),function(key,cb3){                             
                            cashapi.getAccountInfo(token,key,['level'],res){
                                if (err) return cb3(err);                                   
                                accKeys[key].level = res.level;
                                cb3();
                            });
                        },cb2);
                    },function(cb2){                          
                        do {
                            // get current ids
                            var ids = _.reduce(_.values(accKeys),function (memo,item) {
                                memo[item._id] = 1;
                                return memo;
                            },{})
                            // remove accounts that can't be reduced now
                            // accounts that have child or with level
                            // not covered by collapse
                            _.each(accKeys,function (item,id) {
                                delete ids[item.parentId];
                                if (item.level<=params.accLevel)
                                    delete ids[id];
                                if (item.type!=params.accType)
                                    delete ids[id];
                            })
                            // reduce
                            _.each(ids,function (v,id) {
                                var child = accKeys[id];
                                var parent = accKeys[child.parentId];                               
                                parent.summ+=child.summ;
                                parent.expand = 1;
                                if (child.periods) {
                                    for (var i = 0 ; i<child.periods.length; i++) {
                                        parent.periods[i].summ+=child.periods[i].summ;
                                    }                                   
                                }
                                delete accKeys[id];
                            })
                        } while (_.size(ids)!=0);
                        //filter by id and type
                        if(_.isArray(params.accIds) && _.size(accKeys) != params.accIds.length){                                
                            accKeys = _.filter(accKeys,function(elem){
                                if (elem.expand)
                                    return true;
                                return _.find(params.accIds,function(item){return _.isEqual(elem._id.toString(),item.toString())}
                            )});                                        
                        }                                                   
                        accKeys = _(accKeys).reduce(function (memo,acc) {                              
                            if (acc.type == params.accType || acc.expand)
                                memo[acc._id] = acc;                    
                            return memo;
                        },{});     
                        cb2();
                    }
                ],function(err){
                    if(err) return cb1(err);
                    cb1();
                });
            }
            else{                   
                //filter by id and type;
                if(_.isArray(params.accIds) && _.size(accKeys) != params.accIds.length){
                    accKeys = _.filter(accKeys,function(elem){ return _.find(params.accIds,item.toString())})});                                      
                }                       
                accKeys = _(accKeys).reduce(function (memo,acc) {                              
                    if (acc.type == params.accType)
                        memo[acc._id] = acc;                    
                    return memo;
                },{});     
                cb1();
            }
            }))
        },function(cb1){              
            var total = 0;
            // find important accounts (with biggest summ over entire period)
            var iacs = _(accKeys).chain().map(function (acs) { return {_id:acs._id,summ:acs.summ}})
                .sortBy(function (acs) {return acs.summ}).last(params.maxAcc)
                .reduce(function (memo,acs) { memo[acs._id]=1; return memo; },{}).value();
            // colapse non important
            var final = _(accKeys).reduce( function (memo,accKey) {
                total += accKey.summ;
                if (_(iacs).has(accKey._id))
                    memo[accKey._id] = accKey;
                else {
                    var other = memo['other'];
                    if (other==null) {
                        accKey.name = "Other";
                        accKey._id = 'other';
                        memo['other'] = accKey;
                    } else {
                        other.summ+=accKey.summ;
                        if (periods)
                            for(var i =0; i<other.periods.length; i++) {
                                other.periods[i].summ+=accKey.periods[i].summ;
                            }
                    }
                }
                return memo;
            },{});
            // transform into report form
            var report = _(final).reduce( function (memo,accKey) {
                var obj = {};
                if (periods){
                    var obj = {name:accKey.name,data:_(accKey.periods).pluck('summ')}
                } else {
                    obj = [accKey.name,accKey.summ];
                }
                memo.push(obj);
                return memo;
            },[])
            cb1(null,report);

        }
    ],series) {
        if(err) return cb(err);
        if(type == 'pieflow')
            series = {type:'pie',data: series};

        var data = {categories:JSON.stringify(categories),series:JSON.stringify(series)};
        data[type] = 1;
        cb(null,data);
    });
}

我很乐意为您提供帮助。

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)