2012-11-13 131 views
2

我試圖給出for循環參數給內層閉包,因爲我想識別解碼後的音頻(放入緩衝區)。將閉環參數傳遞給閉包內的閉包

此代碼給出錯誤:e未定義。它工作,但是當刪除)(測試),我的意思是測試等於所有結果list.length然而我希望他們有調用當前參數我的值。

for (var i = 0; i < list.length; i++) { //load in every url 
    requestArray.push(new XMLHttpRequest()); 
    requestArray[i].open('GET', list[i].url, true); 
    requestArray[i].responseType = 'arraybuffer'; 
    test = i; 
    requestArray[i].onload = (function (e) { 
     //Async method: ASK J 
     context.decodeAudioData(e.target.response, (function (buffer) { //Async method 
      console.log(test); 
      if (!buffer) { 
       alert('error decoding file data: '); 
       return; 
      } 
     })(test), 

     function (e) { 
      console.log('Error decoding audio file', e) 
     }); 
    })(test); 

    requestArray[i].onerror = function() { 
     alert('BufferLoader: XHR error'); 
    } 

    requestArray[i].send(); 
} 
+0

其中是來自onload的「context」。我很驚訝,不會拋出一個錯誤 – SReject

+0

上下文是在腳本的開始處定義的:它是webaudio的東西,但它與此問題無關:var context = new webkitAudioContext(); – Thomas

回答

2
for (var i=0; i<list.length; i++){ 
    requestArray.push(new XMLHttpRequest()); 
    requestArray[i].open('GET', list[i].url, true); 
    requestArray[i].responseType = 'arraybuffer'; 
    requestArray[i].onload = (function (i) { 
     return function (resp) { 
      // i: index in requestArray 
      // resp: the response object passed when the onload event occurs 

      context.decodeAudioData(
       resp.target.response, 
       (function(test) { 
        return function (buffer) { 
         console.log(test); 
         if (!buffer) { 
          alert('error decoding file data: '); 
          return; 
         } 
        } 
       }(i)), 
       function(e) { console.log('Error decoding audio file', e)} 
      ); 
     } 
    }(i)); 
    requestArray[i].onerror = function() { 
     alert('BufferLoader: XHR error'); 
    } 
    requestArray[i].send(); 
} 



請注意,要創建一個封閉的函數必須返回一個功能。

這是一個封閉:

(function(){ 
    var a = "b"; 
}()); 
+0

但decodeAudioData在哪裏適合? decodeAudioData也是一個回調函數;我的內部封閉在哪裏? – Thomas

1

你的代碼沒有做你想做的事。您不必將test作爲參數進行綁定,而是立即使用參數test調用您的匿名函數,並將其返回的結果作爲參數傳遞給decodeAudioData。我建議先解決這個問題。例如。通過使用Function.prototype.bind

+0

請你詳細說明一下嗎?我對原型製作並不熟悉 – Thomas

+0

這不是關於原型製作。你只需要編寫'myFunc.bind(window,test)',這會將'myFunc'變成一個Function對象,當被調用時,它將把'test'作爲第一個參數傳遞給'myFunc'和'window'作爲'this'(接收器對象)。 –

+0

'.bind'對於某些應用程序來說是一個棘手的函數,因爲它不僅將參數綁定到函數,還綁定了調用者實例。 – SReject

1

我想我會嘗試這樣的語法(我也將採取:

(function(){ 
    var a = "b"; 
    return function(){ alert(b); } 
}()); 


這是當它被視爲評估更多的模塊化方法,具有幾種聲明的功能)

for (var i=0; i<list.length; i++){ //load in every url 
     requestArray.push(new XMLHttpRequest()); 
     requestArray[i].open('GET', list[i].url, true); 
     requestArray[i].responseType = 'arraybuffer'; 
     test = i; 
     requestArray[i].onload = (function(outerIndex){ 
         return function (e) { //Async method: ASK J 
       context.decodeAudioData(e.target.response, 
        (function(index){ 
         return function(buffer) { //Async method 
          console.log(index); 
          if (!buffer) { 
           alert('error decoding file data: '); 
           return; 
          } 
         }; 
        })(outerIndex), function(e) { console.log('Error decoding audio file', e)}); 
     };})(test); 


     requestArray[i].onerror = function() { 
      alert('BufferLoader: XHR error'); 
     } 

     requestArray[i].send(); 
    } 
1

當你把

})(test); 

你在當時運行函數(不是當事件發生時)通過像e這樣的測試。 我不明白「e是未定義的」e是我。

你可以嘗試把「var」定義變量測試,並刪除「)(test)」嗎?我認爲這個問題在測試範圍內。