2013-08-17 34 views
0

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

这里是我的功能代码:

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] }); 
    }); 
}; 

不幸的是“res.render”之后被叫函数只检索1个值,所以我想知道如何做到这一点,或做出适当的回调。

谢谢。

回答

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); 
}) 
+0

对不起,我忘了提,循环是在我的代码很重要,它是用来做一个HTTP GET请求。我将使用全功能代码编辑我的帖子,使其更清晰。 – user2663041

+0

好吧,我明白,但在循环内附加一个监听器并不是一个好主意。它会导致意想不到的结果,因为你有很多函数调用这个* end *事件 – Krasimir

+0

是的,我明白了,那正是我想要避免的,以及为什么我在这里问。 – user2663041

1

调用该函数是异步,响应end事件可以随时发生。而你的代码导致res.render执行5次,但你只需要它用5个值执行1次。你应该使用一个像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 
});