Nodejs - 执行多个回调

时间:2015-07-10 22:12:27

标签: node.js

我使用Step来控制并行执行。 我想做的是:

  1. 使用http读取json文件(json文件包含一系列事件)
  2. 循环事件数组并使用http
  3. 获取事件详细信息
  4. 将活动详情存储在本地变量" events"
  5. 我正在做的事情是这样的:

    
    
    var events = []; // this is the local variable to hold event details
    Step(
    	function getEvents(){
    		
    		var options = {
    			host: '95.85.14.142',
    			port: 80,
    			path: '/data/IT/config.json',
    			method: 'GET'
    		};
    		
    		http.request(options,this).end();
    	
    	},
    	function getEventsResponse(res){
    		
    		if (res.statusCode==200){
    				
    			res.setEncoding('utf8');
    			res.on('data',this);
    			
    		}
    	},
    	function getEventDetails(data){
    		
    		var events = JSON.parse(data).events;
    		
    		var group = this.group();
    		for(e in events){
    			var event = events[e];	
    			var options = {
    				host: '95.85.14.142',
    				port: 80,
    				path: '/data/IT/events/'+event.code+'.json',
    				method: 'GET'
    			};
    			
    			http.request(options,group()).end();
    		
    		}	
    	
    	},
    	function getEventDetailsResponse(err,responses){
    		
    
    		// responses = [undefined,undefined,..] ???
    
    		
    	},
    	...
    );
    
    
    

    getEventDetailsResponse 中,我期待一个对象数组,但我得到一个未定义变量数组:

    [未定义,未定义,..]

    我做错了什么?

1 个答案:

答案 0 :(得分:1)

这是代码的工作版本,以events变量的打印输出结束。我将在下面详细介绍。

var http = require('http');
var Step = require('step');

var events = []; // this is the local variable to hold event details
Step(
    function getEvents(){
        var options = {
            host: '95.85.14.142',
            port: 80,
            path: '/data/IT/config.json',
            method: 'GET'
        };
        http.request(options,this).end();
    },
    function getEventsResponse(res){
        if (res.statusCode==200){
            res.setEncoding('utf8');
            res.on('data',this);
        }
    },
    function getEventDetails(data){
        var events = JSON.parse(data).events;
        var group = this.group();
        for(e in events){
            var event = events[e];
            var options = {
                host: '95.85.14.142',
                port: 80,
                path: '/data/IT/events/'+event.code+'.json',
                method: 'GET'
            };

            (function(){
                var generated_callback = group();
                http.request(options,function(res){generated_callback(null,res);}).end();
            })();
        }
    },
    function getEventDetailsResponse(err,responses){
        var group = this.group();
        for(i in responses){
            var r = responses[i];
            if (r.statusCode==200){
                r.setEncoding('utf8');
                (function(){
                    var generated_callback = group();
                    r.on('data',function(data){
                        var parsed_data = JSON.parse(data);
                        events.push(parsed_data);
                        generated_callback(null,parsed_data);
                    });
                })();
            }
        }
    },
    function displayEvents(err,passed_events){
        console.log("Events Global Variable");
        console.log(events);
        console.log("Passed Events");
        console.log(passed_events);
    }
);

返回:

Events Global Variable
[ { title: 'TITLE 1' },
  { title: 'TITLE 2' },
  { title: 'TITLE 3' } ]
Passed Events
[ { title: 'TITLE 1' },
  { title: 'TITLE 2' },
  { title: 'TITLE 3' } ]

你遇到的问题,我必须深入研究Step代码才能找到,是group()方法生成一个回调,它要求第一个参数是(可能为null)错误对象,第二个参数是成为实际的响应/数据。 http.request只传回响应对象,Step将其解释为错误。

要解决此问题,您可以手动调用组函数来生成回调,然后使用null first参数手动调用回调。既然这都是异步的,你需要将它包装在一个自调整闭包中以隔离和持久化生成的回调,否则每次都会被覆盖,当第一个请求返回时它会尝试调用回调函数。生成的第三个 - 或其他 - 请求而不是它自己的请求。您可以在我的getEventDetails函数版本中看到包含http.request的内容,以及getEventDetailsResponse函数中稍微复杂的示例。

作为旁注,在脚本顶部声明的事件变量是全局变量,而不是本地变量。在getEventDetails中声明的是一个局部变量。如果您打算使用var events = JSON.parse(data).events;将数据设置到全局变量上,那么您可以通过从该行中删除'var'来实现。