2015-07-10 79 views
0

我正在使用Step來控制並行執行。 我試圖做的是:Nodejs - 多個回調函數

  1. 使用http讀取一個JSON文件(JSON文件包含事件的數組)
  2. 循環事件的陣列並得到事件的細節使用http
  3. 存儲事件的詳細信息在一個局部變量的「事件」

我在做什麼是成才這樣的:

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

 
\t \t // responses = [undefined,undefined,..] ??? 
 

 
\t \t 
 
\t }, 
 
\t ... 
 
);

getEventDetailsResponse我期待對象的數組,但我得到了一個未定義的數組變量:

[不確定的,不確定的,..]

我在做什麼錯誤?

回答

1

這是您的代碼的工作版本,以事件變量的打印輸出結束。我將在下面詳細介紹。

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' } ] 

你正在運行之中,我不得不挖掘到步驟代碼中查找出來的問題,是該集團()方法生成預計回調第一個參數是(可能爲null)錯誤對象,第二個參數是實際的響應/數據。 http.request只傳遞響應對象,Step正在將它解釋爲錯誤。

要解決該問題,您可以手動調用組函數來生成回調,然後使用空的第一個參數手動調用回調。由於這些都是異步的,所以你需要將它封裝在一個自調用閉包中以隔離並持久化生成的回調,否則每次都會被覆蓋,當第一個請求返回時它會嘗試調用回調函數爲第三個或其他任何請求生成而不是自己的請求。你可以在我的getEventDetails函數版本中看到包裹在http.request中,以及getEventDetailsResponse函數中稍微複雜一些的例子。

作爲一個方面說明,腳本頂部聲明的events變量是一個全局變量,不是本地變量。在getEventDetails中聲明的是一個局部變量。如果你想用var events = JSON.parse(data).events;將數據設置到全局變量上,那麼你可以通過從該行刪除'var'來完成。

+0

仍然無法讓它工作... – Franz

+0

我可能導致你誤入歧途。我將使用腳本的工作版本編輯答案。 –