2017-05-30 111 views
1

我是JavaScript新手。這裏是我的代碼可變變量可從閉包訪問

...... 
var filename, result, user=["a", "b", "c","d"]; 
for(var p=0;p<user.length;p++) 
     { 
     filename=userID[p]+'_'+user[p]+'.json'; 

     fs.readFile(filename, function read(err, data) 
     { 
      if (err) {throw err;} 
      result = data.toString(); 

      if (result.charAt(result.length-1) === ',') 
      result = result.substring(0,result.length-1) + ']}'; 

      console.log(p+filename+result+"\n\n"); //here 

      }); 

     } 

在「這裏」 P的值總是顯示最後一個索引,在這種情況下3的各個版本中也文件名是最後我iteration.How可以得到正確的p在「here」中的值。對於我的編譯器顯示「可變變量是可以從閉包訪問」。

+3

這是因爲'readFile'是異步的,到'read'被調用時,'p'已經遞增到'3'。使用[let binding](https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Statements/let)(即'let p = 0')而不是'var'。或者你可以使用'user.forEach' – naomik

回答

1

@naomik評論似乎對任何在循環體內的異步工作總是不好的主意。因爲循環不會等到響應。

var filename, result, user=["a", "b", "c","d"]; 
var p=0; 
function readfileUnitil(p) 
    { 
    filename=userID[p]+'_'+user[p]+'.json'; 

    fs.readFile(filename,function(err, data) 
    { 
     if (err) {throw err;} 
     result = data.toString(); 

     if (result.charAt(result.length-1) === ',') 
     result = result.substring(0,result.length-1) + ']}'; 

     console.log(p+filename+result+"\n\n"); //here 
     if(p<user.length){ 
     p++; 
     readfileUnitil(p); 
     } 
     }); 
    } 
} 

我做喜歡這種遞歸的,而不是讓變量,因爲這是更具可讀性和記憶不會被瀏覽器希望幫助舉行。

1

filename這種情況下範圍for loop塊,filename值已經結合fs.readFile。簡單的方法來解決這個問題,請按照塊代碼

var filename, result, user = ["a", "b", "c", "d"]; 
for (var p = 0; p < user.length; p++) { 
    filename = userID[p] + '_' + user[p] + '.json'; 

    (function(file) { 
     fs.readFile(filename, function read(err, data) { 
      if (err) { 
       throw err; 
      } 
      result = data.toString(); 

      if (result.charAt(result.length - 1) === ',') 
       result = result.substring(0, result.length - 1) + ']}'; 

      console.log(p + filename + result + "\n\n"); //here 

     }); 

    })(filename) 

}