2012-03-03 122 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解决方案。