2011-10-06 85 views
0

我怎樣才能得到那個返回值?而不是:從關閉中返回一個變量

this.setCanvas = function(files){ 
    var numItems = files.length - 1; 
    this.items = {}; 

    var i = 0; 
    for(i=0;i<=numItems;i++) 
    { 
    var file = files[i]; 
    var reader = new FileReader(); 

    reader.onload = (function(i) { 
     return function(e) { 
     var something = that.whatever(); 
     items[i] = something; 
     }; 
    })(i); 

    reader.readAsDataURL(file); 
    } 

console.log(items); 
} 

我需要項目[i]定義。如果我在閉包之外的console.log items [i]它是未定義的。

回答

1

您可以增加代碼以跟蹤加載的文件數量。這樣,當最後一個文件已加載,你可以調用最終完成處理程序:

this.setCanvas = function(files) { 
    var numItems = files.length - 1; 
    var itemsLoaded = 0; // Initialize to zero 

    var items = []; 

    var i = 0; 
    for(i=0;i<=numItems;i++) { 

     var file = files[i]; 
     var reader = new FileReader(); 

     reader.onload = (function(i) { 
     return function(e) { 
      var something = that.whatever(); 
      items[i] = something; 

      if(++itemsLoaded == numItems) { 
      // At this point all files will have been loaded. 
      allLoaded(); 
      } 
     }; 
     })(i); 

     reader.readAsDataURL(file); 
    } 

    function allLoaded() { 
     // Now we can analyze the results 
     console.log(items); 
    } 
    } 

我也改變items是一個Array而不是Object

此外,如果你想要更聰明一點,你可以遞減numItems並檢查零而不是創建一個新的itemsLoaded變量。

+0

謝謝。我最終通過函數傳遞了項目。你的榜樣讓我朝着正確的方向前進。我仍然不完全理解這一切,但這是一個完整的問題。 ) –

+0

剛做了一個小小的更新。而不是'this.items = []',我只是將它作爲一個變量,這允許閉包(處理程序)更容易地訪問它;否則'onload'處理程序將不知道在試圖獲取「items」時要使用哪個'this'。僅供參考,'onload'處理程序由JavaScript引擎調用,您會發現'this'引用指向'reader'實例。 – Peter

2

問題不在關閉;這是回調。無論需要使用that.whatever的值需要在回調中執行

0

這裏有幾件事情需要改變。首先將this.items設置爲一個數組。接下來將此分配給自己,以便可以在閉包中引用它。接下來將這些內容分配給self.items [i]而不是項目[i]。最後在console.log中使用this.items

this.setCanvas = function(files){ 
    var self = this; 
    var numItems = files.length - 1; 
    this.items = []; 

    var i = 0; 
    for(i=0;i<=numItems;i++) 
    { 
    var file = files[i]; 
    var reader = new FileReader(); 

    reader.onload = (function(i) { 
     return function(e) { 
     var something = that.whatever(); 
     self.items[i] = something; 
     }; 
    })(i); 

    reader.readAsDataURL(file); 
    } 

    console.log(this.items); 
}