Проблема с областью действия с xmlhttprequest и API веб-аудио?

Я новичок в JS, и я пытался реализовать своего рода звуковой микшер с API веб-аудио. Я немного читал о возможностях JS и различных способах реализации «классов», но, очевидно, я еще не совсем в этом разбираюсь. У меня есть этот объект soundClass, который я бы хотел, чтобы он содержал массив объектов track, и я хотел бы push создать новый track на tracklist, как только он будет декодирован. Однако всякий раз, когда я console.log tracklist или каждый track, как показано ниже, первый журнал (console.log('track name '+ that.track.name);) показывает правильное имя дорожки, но если я пытаюсь зарегистрировать сам объект that.track, он всегда показывает последнюю добавленную дорожку, поэтому, если я вызываю soundClass.newTrack('track1.mp3') и soundClass.newTrack('track2.mp3') и console.log(soundClass.tracklist) я получаю массив с двумя объектами track2.mp3. Я предполагаю, что это проблема области или проблема с асинхронным декодированием, но на самом деле я понятия не имею, так что это может быть просто какая-то глупая ошибка.

Извините, если это действительно простой вопрос, но я был бы признателен за любую помощь.

var soundClass = {

audioContext: new webkitAudioContext,
currentTime: 0,
track: {
    name: 0,
    trackSource: null,
    trackBuffer:null,
    isLoaded: false,
},
tracklist: [],
newTrack: function(filename){
    var that=this;      
    var request =new XMLHttpRequest();
    request.open("GET",filename,true);
    request.responseType="arraybuffer";
    request.onload=function(){
            that.audioContext.decodeAudioData(request.response,function(buffer){

                that.track.trackBuffer=buffer;
                that.track.name=filename;
                that.track.isLoaded=true;
                that.track.trackSource=that.audioContext.createBufferSource();

                console.log('track name '+ that.track.name);
                console.log(that.track);

                that.tracklist.push(that.track);

                });

    }
    request.send();
},

person poeschl    schedule 29.04.2013    source источник


Ответы (1)


У вас есть только один объект soundclass.track. В функции request.onload вы снова и снова изменяете один и тот же объект. Таким образом, ваш tracklist содержит один и тот же объект дважды. Что вы можете сделать, это

var track = {};
track.trackBuffer=buffer;
...
that.tracklist.push(track);

и избавьтесь от soundclass.track.

person a better oliver    schedule 29.04.2013
comment
Спасибо !, с моей стороны было действительно глупо помещать track в качестве литерала внутри soundclass. Но мне все равно интересно, почему так происходит. Даже если я перезаписывал track, я сначала добавлял его к массиву tracklist, так что массив должен быть в порядке? в любом случае, еще раз спасибо! - person poeschl; 29.04.2013
comment
Массив в порядке. Не могли бы вы принять ответ, если он работает для вас? :) - person a better oliver; 29.04.2013
comment
Но тогда почему вывод журнала списка дорожек был только последним добавленным объектом столько раз, сколько было вызвано newTrack?. - person poeschl; 29.04.2013
comment
Есть только один объект. Сначала вы устанавливаете его значения в track1.mp3 и т. д. и добавляете его в массив. tracklist[0] указывает на track, который имеет значение track1.mp3. Затем вы меняете значение и снова добавляете его в массив. tracklist[1] теперь также указывает на track, а track имеет значение track2.mpg. tracklist[0] по-прежнему указывает на track, конечно. А значение track равно ... track2.mp3 ^^ - person a better oliver; 29.04.2013