2012-03-03 121 views
0

基本上我想通過現有的arrtickers來遍歷每個符號node.js異步問題?

然後閱讀每個符號url內的內容並將內容保存到本地目錄中。

在php中,它會逐步打印出每個代碼和每個符號。

但是在節點中,序列搞砸了。

它會打印出所有的url_optionable第一...

則有時打印的console.log( '路徑:' +文件),有時打印的console.log( 「文件被保存!」);

每次通過fs.writefile功能運行,未檢測到符號價值,保存的文件顯示爲MSN-的.html

for(var v=0;v<arrtickers.length;v++) 
{ 
    var arrticker= arrtickers[v].split('@@'); 
    var sym= $.trim(arrticker[1]); 

    url_optionable= "http://sample.com/ns/?symbol="+sym; 

    console.log('url_optionable: ' + url_optionable); 

    request({ uri:url_optionable }, function (error, response, body) { 
     if (error && response.statusCode !== 200) { 
     console.log('Error contacting ' + url_optionable) 
     } 

     jsdom.env({ 
     html: body, 
     scripts: [ 
      jqlib 
     ] 
     }, function (err, window) { 

     var $ = window.jQuery; 
     var data= $('body').html(); 

     var file= "msn-"+sym+".html"; 
     console.log('path: ' + file); 

     fs.writeFile(file, data, function(err) { 
      if(err) { 
      console.log(err); 
      } 
      else 
      { 
       console.log("The file was saved!"); 
       } 
     }); 
     }); 
    }); 
} 
+1

我看到的一個問題就是你循環。在回調運行的地方,循環運行並且循環中的變量被設置爲最後一次運行的值。你可能想用'arrtickers.forEach()'來產生一個閉包。 – ZeissS 2012-03-03 17:03:29

+0

謝謝你,forEach是異步的訣竅。 :) – 2012-03-04 11:20:26

回答

1

ZeissS是正確的。基本上,你不能在回調函數中使用for循環中聲明的變量來進行異步調用,因爲它們都將被設置爲循環中的最後一個值。因此在您的代碼中,url_optionablesym將對應於arrtickers[arrtickers.length - 1]

要麼使用(如ZeissS建議):

arrtickers.forEach(function(arrticker) { 
    // Get symbol and url, make request etc 
}); 

或聲明函數,它接受sym並執行請求,調用在循環:

function getSymbol(symbol) { 
    // Request url and read DOM 
} 

for(var v=0;v<arrtickers.length;v++) { 
    var arrticker = arrtickers[v].split('@@'); 
    var sym = $.trim(arrticker[1]); 

    getSymbol(sym); 
} 

就個人而言,我會選擇爲forEach解決方案。