0

How do I access the globalBuffer variable after setting it in the request.onload callback? I'm learning more about closures, but don't understand why I'm unable to set the value and retrieve it after the fact. In other words, why does console.log(globalBuffer) return undefined?

var globalBuffer;
var context = new webkitAudioContext();

function loadSound(url) {
    var request = new XMLHttpRequest();
    request.open("GET", url, true);
    request.responseType = "arraybuffer";

    request.onload = function() {
        context.decodeAudioData(request.response, function(buffer) {
                // I want to set globalBuffer and retrieve it outside the function
                globalBuffer = buffer;
            }    
        );
    }
    request.send();
}

loadSound("http://upload.wikimedia.org/wikipedia/en/9/9e/Metallica_-_For_Whom_the_Bell_Tolls_%28song%29.ogg");

console.log(globalBuffer);

Edit:

Codepen

Levi V
  • 78
  • 1
  • 7
  • you can reach it from anywhere after you set it. try pasting your last line into the console once the code runs and you'll see what i mean. – dandavis Jun 14 '14 at 01:35
  • Tried that– `globalBuffer` comes back as `undefined`. If I run `console.log(globalBuffer)` inside the `onload` function, it returns the object, which makes sense, asynchronously. I figured `onload` would fire after everything had loaded, and then I'd be ok to set the variable and retrieve it for later use. – Levi V Jun 14 '14 at 02:00

1 Answers1

0

loadSound is asynchronous method, and console.log is synchronous - is not waiting till loadSound will end. globalBuffer is declarated with value undefined and this value is returned without waiting for finish loadSound

proof of concept how it can be solved:

function loadSound(url, callback) {
  setTimeout(function() {
    return callback('loaded song from: ' + url)
  }, 1000);
}

loadSound('url to sound clip', function(response) {
  console.log(response);
});

setTimeout is for simulating asynchronous action - if data is available - callback function is calling.

Krzysztof Safjanowski
  • 7,292
  • 3
  • 35
  • 47
  • I see how that works, and am able to access it through the callback function, but I'm still unable to access it globally. Check out this [CodePen](http://codepen.io/levivoelz/pen/ikICf?editors=001). – Levi V Jun 14 '14 at 02:13
  • Still console.log runs before loadSound finish execution. To check this set some value to globalBuffer in first line and than chack what console.log will return. – Krzysztof Safjanowski Jun 14 '14 at 02:28