2

デコードされたオーディオ (バッファー内に配置されている) を識別したいので、 for ループ パラメーター i を内側のクロージャーに与えようとしています。

このコードはエラーを出します: e は定義されていません。ただし、 )(test) を削除すると機能します。これは、すべての結果に対して test が list.length と等しいことを意味しますが、呼び出されたときに現在のパラメーター i の値が必要です。

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();
}
4

4 に答える 4

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";
    return function(){ alert(b); }
}());


これは、次のようにすぐに評価されます。

(function(){
    var a = "b";
}());
于 2012-11-13T15:41:59.003 に答える
1

あなたが置くとき

})(test);

その時点で (イベントが発生したときではなく) 関数を実行すると、e のようなテストに合格します。「e is undefined」がわかりません e is i.

変数 test を定義する場所に "var" を置き、")(test)" を削除してみてください。問題はテストの範囲内だと思います。

于 2012-11-13T15:59:09.770 に答える
1

私はこのような構文を試すと思います(いくつかの宣言された関数を使用して、よりモジュラーなアプローチもとります)

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();
    }
于 2012-11-13T15:51:28.133 に答える
1

あなたのコードは、あなたが望むことをしません。引数としてバインドする代わりにtest、引数を使用して匿名関数をすぐに呼び出し、test返された結果を引数として に渡しますdecodeAudioData。最初にこれを修正することをお勧めします。たとえば、Function.prototype.bindを使用します。

于 2012-11-13T15:41:03.930 に答える