javascript closure Uncaught TypeError:无法读取undefined的属性'request'

时间:2017-07-01 16:33:56

标签: javascript closures typeerror web-audio-api

我正试图通过使用for循环迭代整个过程以获取对象列表来减少之前有效的重复代码。

var context = new (window.AudioContext || window.webkitAudioContext)();

//Set up the objects for each part
var solo = { audio: context.createBufferSource(),
     audioData: context.createBufferSource(),
     file: "mp3s/Faith_solo.mp3",
     request: new XMLHttpRequest(),
     isPlaying: false,
     startTime: null,
     seekAsOfLastPause: 0,
     duration: 0
        }
var t1 = { audio: context.createBufferSource(),
   audioData: context.createBufferSource(),
   file: "mp3s/Faith_t1.mp3",
   request: new XMLHttpRequest(),
   isPlaying: false,
   startTime: null,
   seekAsOfLastPause: 0,
   duration: 0
     }
var t2 = { audio: context.createBufferSource(),
   audioData: context.createBufferSource(),
   file: "mp3s/Faith_t2.mp3",
   request: new XMLHttpRequest(),
   isPlaying: false,
   startTime: null,
   seekAsOfLastPause: 0,
   duration: 0
        }
var baritone = {
     audio: context.createBufferSource(),
     audioData: context.createBufferSource(),
     file: "mp3s/Faith_baritone.mp3",
     request: new XMLHttpRequest(),
     isPlaying: false,
     startTime: null,
     seekAsOfLastPause: 0,
     duration: 0
        }
var bass = { audio: context.createBufferSource(),
     audioData: context.createBufferSource(),
     file: "mp3s/Faith_bass.mp3",
     request: new XMLHttpRequest(),
     isPlaying: false,
     startTime: null,
     seekAsOfLastPause: 0,
     duration: 0
       }

var allParts = [solo, t1, t2, baritone, bass];

/* create requests, send requests, load files */

for(i=0;i<allParts.length;i++){
    allParts[i].request.open("GET", allParts[i].file, true);
    allParts[i].request.responseType = "arraybuffer";
    allParts[i].request.onload = function(){
        **context.decodeAudioData(allParts[i].request.response, onDecoded);**
    }
    function onDecoded(buffer){
        allParts[i].audioData.buffer = buffer;
    }
    allParts[i].request.send();
}

我得到了错误的五个副本:“Uncaught TypeError:无法在XMLHttpRequest.allParts。(匿名函数).request.onload”读取未定义的属性'请求'在我设置的星号所包围的行上context.decodeAudioData参数。

我不太清楚为什么会这样。我被告知这是一个闭包问题,但我一直无法找到修复它的方法,我不太明白为什么它会成为一个闭包问题。 XMLHttpRequest是在代码运行之前创建的,它超出了匿名函数的范围,所以它应该可以在那里访问。

感谢您的帮助!

1 个答案:

答案 0 :(得分:0)

您需要使用let在循环中定义i。或者使用forEach或allParts.map

for(let i=0;i<allParts.length;i++){ ...

allParts.map(function(part, i){ ... })