Node.js中的Functionscope和Callback

时间:2013-02-14 21:54:14

标签: javascript node.js

所以我必须在循环中计算一些share。在该循环的每次迭代中,我必须从数组中获取名为rent的变量。所以我从数据库中删除了calculate函数。

var calculate = function() {
    while(count < 100) {
        var share = 50;
        var shareArray = [];

        for(var i = 0; i < 100; i++) {

            var pension = share*2; // mathematical stuff
            // Gets a rent from a database and returns it in a callback
            getRent(modules, share, function(rent) {
                share = rent*foo; // some fancy mathematical stuff going on here
                // I need to get the share variable above out of its function scope
            });
                    // I need the share variable right here
            shareArray.push(share);     // the value of share will be for i = 0: 50, i= 1: 50 ...
                                        // This is not what i want, i need the share value from getRent()
        }
        count++;
    }
}

现在您可能会看到我遇到以下问题。因为我在node.js中工作,从modules数组中获取rent变量的唯一方法是通过这个名为getRent()的回调函数。问题是,在此步骤之后我需要share值,但在getRent()之外。 我有什么方法可以做到这一点吗?

这是getRent() - 功能:

var getRent = function(modules, share, callback) {
        // Searching for a fitting rent in the modules array
        // Just assume this is happening here
        callback(rent);
};

所以问题是:我如何“返回”share

getRent(modules, share, function(rent) {
                    share = rent*foo; // some fancy mathematical stuff going on here
                    // I need to get the share variable above out of its function scope
});

以任何方式?

2 个答案:

答案 0 :(得分:1)

如果getRent是异步的,则无法同步获得结果。从根本上说,你不知道getRent在最终返回它之前最终会为其回调提供的值。所以它不是功能范围的问题,而是时间问题。您只需等待getRent执行此操作,然后才能获得rent的值。您需要重构代码,以便calculate也是异步。

类似的东西:

// Refactor calculate to be async:
function calculate(cb) {
    var data = [];
    for ( var i=0; i<100; i++ ) {
        getRent(function (rent) {
            data.push(rent);
            if ( data.length === 100 ) cb(data);
        });
    }
}

// And then use it async:
calculate(function (data) {
    // data array arrives here with 100 elements
});

上面的回答可能类似于你如何使用vanilla JS实现它。从长远来看,使用像miggs这样的async库可能是一个好主意。但就像我说的那样,如果你使用vanilla JS或async lib,那么你不得不在这段代码和调用它的代码中重构异步性这一事实。

答案 1 :(得分:0)

您希望使用whilst库(npm install async)的async方法来简化此操作:

var count = 0;
var shareArray = [];

async.whilst(
    function () { 
        return count < 100; 
    },
    function (next) {
        count++;
        getRent(function(rent) {
            // What does modules do anyway??
            // Dont know where foo comes from...
            shareArray.push(rent*foo); // some fancy mathematical stuff going on here
            next();
        });
    },
    function (err) {
        console.log(shareArray);
        // Do sth. with shareArray
    }
);

如果你可以并行请求所有100个电话,你也可以使用parallel功能。