Friday 15 March 2013

javascript - Why is my variable unaltered after I modify it inside of a function? - Asynchronous code reference -



javascript - Why is my variable unaltered after I modify it inside of a function? - Asynchronous code reference -

given next examples, why outerscopevar undefined in cases?

var outerscopevar; var img = document.createelement('img'); img.onload = function() { outerscopevar = this.width; }; img.src = 'lolcat.png'; alert(outerscopevar);

var outerscopevar; settimeout(function() { outerscopevar = 'hello asynchronous world!'; }, 0); alert(outerscopevar);

// illustration using jquery var outerscopevar; $.post('loldog', function(response) { outerscopevar = response; }); alert(outerscopevar);

// node.js illustration var outerscopevar; fs.readfile('./catdog.html', function(err, data) { outerscopevar = data; }); console.log(outerscopevar);

// promises var outerscopevar; mypromise.then(function (response) { outerscopevar = response; }); console.log(outerscopevar);

why output undefined in of these examples? don't want workarounds, want know why happening.

note: canonical question javascript asynchronicity. sense free improve question , add together more simplified examples community can identify with.

one word answer: asynchronicity.

forewords

this topic has been iterated @ to the lowest degree couple of thousands times, here, in stack overflow. hence, first off i'd point out extremely useful resources:

@felix kling's "how homecoming response ajax call". see first-class reply explaining synchronous , asynchronous flows, "restructure code" section. @benjamin gruenbaum has set lot of effort explaining asynchronicity in same thread.

@matt esch's reply "get info fs.readfile" explains asynchronicity extremely in simple manner.

the reply question @ hand

let's trace mutual behavior first. in examples, outerscopevar modified within of function. function not executed immediately, beingness assigned or passed argument. phone call callback.

now question is, when callback called?

it depends on case. let's seek trace mutual behavior again:

img.onload may called sometime in future, when (and if) image has loaded. settimeout may called sometime in future, after delay has expired , timeout hasn't been cancelled cleartimeout. note: when using 0 delay, browsers have minimum timeout delay cap (specified 4ms in html5 spec). jquery $.post's callback may called sometime in future, when (and if) ajax request has been completed successfully. node.js's fs.readfile may called sometime in future, when file has been read or thrown error.

in cases, have callback may run sometime in future. "sometime in future" refer asynchronous flow.

asynchronous execution pushed out of synchronous flow. is, asynchronous code never execute while synchronous code stack executing. meaning of javascript beingness single-threaded.

more specifically, when js engine idle -- not executing stack of (a)synchronous code -- poll events may have triggered asynchronous callbacks (e.g. expired timeout, received network response) , execute them 1 after another. regarded event loop.

that is, asynchronous code highlighted in hand-drawn reddish shapes may execute after remaining synchronous code in respective code blocks have executed:

in short, callback functions created synchronously, executed asynchronously. can't rely on execution of asynchronous function until know has executed, , how that?

it simple, really. logic depends on asynchronous function execution should started/called within asynchronous function. example, moving alerts , console.logs within callback function output expected result, because result available @ point.

implementing own callback logic

often need more things result asynchronous function, or different things result depending asynchronous function has been called. let's tackle bit more complex example:

var outerscopevar; hellocatasync(); alert(outerscopevar); function hellocatasync() { settimeout(function() { outerscopevar = 'nya'; }, math.random() * 2000); }

note: i'm using settimeout random delay generic asynchronous function, same illustration applies ajax, readfile, onload , other asynchronous flow.

this illustration suffers same issue other examples, not waiting until asynchronous function executes.

let's tackle implementing callback scheme of our own. first off, rid of ugly outerscopevar useless in case. add together parameter accepts function argument, our callback. when asynchronous operation finishes, phone call callback passing result. implementation (please read comments in order):

// 1. phone call hellocatasync passing callback function, // called receiving result async operation hellocatasync(function(result) { // 5. received result async function, // whatever want it: alert(result); }); // 2. "callback" parameter reference function // passed argument hellocatasync phone call function hellocatasync(callback) { // 3. start async operation: settimeout(function() { // 4. finished async operation, // phone call callback passing result argument callback('nya'); }, math.random() * 2000); }

most in real utilize cases, dom api , libraries provide callback functionality (the hellocatasync implementation in demonstrative example). need pass callback function , understand execute out of synchronous flow, , restructure code accommodate that.

you notice due asynchronous nature, impossible return value asynchronous flow synchronous flow callback defined, asynchronous callbacks executed long after synchronous code has finished executing.

instead of returning value asynchronous callback, have create utilize of callback pattern, or... promises.

promises

although there ways maintain callback hell @ bay vanilla js, promises growing in popularity , beingness standardized in es6 (see promise - mdn).

promises (a.k.a. futures) provide more linear, , pleasant, reading of asynchronous code, explaining entire functionality out of scope of question. instead, i'll leave these first-class resources interested:

javascript promises - html5 rocks you're missing point of promises - domenic.me more reading material javascript asynchronicity the fine art of node - callbacks explains asynchronous code , callbacks vanilla js examples , node.js code well.

note: i've marked reply community wiki, hence @ to the lowest degree 100 reputation can edit , improve it! please sense free improve answer, or submit new reply if you'd well.

i want turn question canonical topic reply asynchronicity issues unrelated ajax (there how homecoming response ajax call? that), hence topic needs help , helpful possible!

javascript asynchronous

No comments:

Post a Comment