0

我在我的应用程序代码中遇到了一个问题,我想知道处理它的最佳方法:我有一个在回调上应用 5 个值的函数,我想知道使用它的最佳方法。

这是我的功能代码:

var someFunc = function(callback) {
var http = require('http');
var id;
var url = 'http://somesite.com/json';


// First request to get an array of 5 elements
http.get(url, function(res) {
    var body = '';

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

    res.on('end', function() {
        var jsonResult = JSON.parse(body);
// 5 requests with a value from each of the 5 elements
        for (var i=0;i<5;i++)
        {
            (function(idx) {
                gameId = jsonResult.gameList[idx].id;
                url = 'http://somesite.com' + id + '/token';
                http.get(url, function(res) {
                    var body = '';

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

                    res.on('end', function() {
                        jsonRes = JSON.parse(body);
                        callback.apply(null, [idx, jsonRes.interestScore]);
                    });
                }).on('error', function(e) {
                    console.log("Got error: ", e);
                });
            })(i);
        }

    });
}).on('error', function(e) {
    console.log("Got error: ", e);
});
};
exports.someFunc = someFunc;

当我调用函数来检索 5 个值时,我会这样做:

exports.featured = function(req, res){
    getSome.someFunc(function callback(result) {
        var variables = {};
        var variableName = result;
        variables[variableName] = jsonRes.interestScore;
        res.render('featured', { score0: variables[0], score1: variables[1], score2: variables[2], score3: variables[3], score4: variables[4] });
    });
};

不幸的是,在函数只检索到 1 个值之后调用了“res.render”,所以我想知道如何正确地执行它,或者进行正确的回调。

谢谢。

4

2 回答 2

1

你调用的函数是异步的,响应end事件可以随时发生。并且您的代码会导致res.render执行 5 次,但您只需要它执行 1 次和 5 个值。您应该使用像async这样的模块,它可以帮助您触发多个任务,并在所有任务完成时回调。

例子:

var jsonResult = JSON.parse(body);
var arr = [];
for(var i = 0; i < 5; i++){
   arr.push(jsonResult[0].interestScore);
}
async.map(arr, myAsyncFunction, function(err, results){
   // results[0] => response of first index
   // results[4] => response of last index
});
于 2013-08-17T08:18:50.150 回答
0

我看到的第一个问题是您为结束事件分配了五次侦听器。你应该只做一次。您可以收集五次结果,然后调用回调。这是一个使用请求模块的示例:

var request = require('request');

var makeRequests = function(callback) {
    var result = [],
        done = 0;
    request('http://www.google.com', function (error, response, body) {
        if (!error && response.statusCode == 200) {
            // read the body here
            var searchFor = [
                'nodejs',       // 1
                'http request', // 2
                'npm',          // 3
                'express',      // 4
                'javascript'    // 5
            ];
            for(var i=0; keyword = searchFor[i]; i++) {
                request('https://www.google.bg/search?q=' + keyword, function (error, response, body) {
                    if (!error && response.statusCode == 200) {
                        result.push(body);
                        ++done;
                        if(done == searchFor.length) {
                            callback(result);
                        }
                    }
                });
            }
        }
    });
}

makeRequests(function(result) {
    console.log("result=" + result.length);
})
于 2013-08-17T08:12:53.787 回答