无序循环响应的异步回调

时间:2014-02-24 15:03:48

标签: javascript node.js asynchronous callback

我在for循环中进行异步调用,我知道响应是异步的,但我怎么能以相同的顺序得到我的响应。这是我的代码:

setInterval(function () {
    callback = function (response) 
    {
        var temp2 = '';
        var str = "";
        test = [];
        console.log('STATUS: ' + response.statusCode);
        response.setEncoding('utf8');
        response.on('data', function (chunk) 
        {
            str += chunk;
        });

        response.on('end', function () 
        {
            console.log("end found");
            temp2 = JSON.parse(str);
            for (var i in temp2['build']) 
            {
                test.push(temp2['build'][i]['id']);
                var req3 = http.request({
                    host: host, // here only the domain name
                    auth: auth,
                    port: 8111,
                    path: '/httpAuth/app/rest/builds/id:' + test[i] + '/statistics/', // the rest of the url with parameters if needed
                    method: 'GET', // do GET
                    headers: { "Accept": "application/json" }
                }, callback2);
                req3.end();
            }
        });
    }

    var req4 = http.request(options4, callback);
    req4.end();


    callback2 = function (response) {

        //console.log('STATUS: ' + response.statusCode);
        //console.log('HEADERS: ' + JSON.stringify(response.headers));
        response.setEncoding('utf8');
        var str2 = "";
        response.on('data', function (chunk) {
            str2 += chunk;
        });

        response.on('end', function () {
            points.push(parseInt(JSON.parse(str2)["property"][2]["value"]));

        });
        j++;
        if (j == test.length) {
            var sumTotal = 0;
            var sumThree = 0;
            var status = '';
            for (var i in points) {
                sumTotal += points[i];
            }
            var averageTotal = parseInt(Math.round(sumTotal / points.length));
            for (var i = 0; i < 3; i++) {
                sumThree += points[i];
            }
            var averageThree = parseInt(Math.round(sumThree / 3));
            /*if(averageThree>averageTotal)
            {
                status='warning';
            }
            else
            {
                status='ok';
            }*/
             console.log('average: ' + averageThree + ' average 100 ' + averageTotal + ' status ' + status);
            //send_event('speed', {current: averageThree/*, status: status*/, last: averageTotal});
            j = 0;
            points = [];
        }
    }
}, 15 * 1000);

所以我的问题是我怎么能确定我的回答'点'总是有相同的顺序。我已经尝试将var i发送到回调函数但无法使其工作

编辑: 改变了格式。 第一个回调的输出:

{
"count":100,
"nextHref":"/httpAuth/app/rest/builds/?locator=buildType:bt2,count:100,status:SUCCESS,start:100",
"build":[
    {
    "id":17469,
    "number":"5075",
    "status":"SUCCESS",
    "buildTypeId":"bt2",
    "startDate":"20140224T183152+0100",
    "href":"/httpAuth/app/rest/builds/id:17469",
    "webUrl":"http://x.x.x.x:8111/viewLog.html?buildId=17469&buildTypeId=bt2"
    },
    {
    "id":17464,
    "number":"5074",
    "status":"SUCCESS",
    "buildTypeId":"bt2",
    "startDate":"20140224T165758+0100",
    "href":"/httpAuth/app/rest/builds/id:17464",
    "webUrl":"http://x.x.x.x:8111/viewLog.html?buildId=17464&buildTypeId=bt2"
    },
    {
    "id":17461,
    "number":"5073",
    "status":"SUCCESS",
    "buildTypeId":"bt2",
    "startDate":"20140224T161852+0100",
    "href":"/httpAuth/app/rest/builds/id:17461",
    "webUrl":"http://x.x.x.x:8111/viewLog.html?buildId=17461&buildTypeId=bt2"
    },

此输出包含100个项目。从这个输出中我获取id号并使用这个id数组发出一个新请求。这个新的回调给了我构建持续时间,但问题是因为这是异步发生的,我得到的响应不是来自最新版本,而是来自第一个响应。所以我的问题是如何才能以正确的顺序获得这些构建速度数组

1 个答案:

答案 0 :(得分:1)

不建议在for循环中使用匿名函数。

最好的方法(对我来说),就是使用异步库。

一个简单的例子来回答你的问题:

var objectList = [
    {"name":"Doe", "firstname":"John", "position":1},
    {"name":"Foo", "firstname":"Bar", "position":2},
    {"name":"Gates", "firstname":"Bill", "position":3},
    {"name":"Jobs", "firstname":"Steve", "position":4},
];
var arr = [];

async.each(objectList, function(person, callback) {
    arr.push(person); // async.each is asynchronous, so at the end, the order will be bad
}, function(err) {        
    async.sortBy(arr, function(p, callback) { // Reorder
        callback(err, p.position);
    }, function(err, results) {            
        callback(null, results); // Send the result
    });
});

此示例适用于您的问题。