{"id":3054,"date":"2013-12-16T15:04:16","date_gmt":"2013-12-16T21:04:16","guid":{"rendered":"http:\/\/bililite.com\/blog\/?p=3054"},"modified":"2013-12-16T15:04:16","modified_gmt":"2013-12-16T21:04:16","slug":"thinking-about-synchonicity","status":"publish","type":"post","link":"https:\/\/bililite.com\/blog\/2013\/12\/16\/thinking-about-synchonicity\/","title":{"rendered":"Thinking about synchonicity"},"content":{"rendered":"<p>I've been looking at <a href=\"http:\/\/promises-aplus.github.io\/promises-spec\/\">Promise\/A+<\/a> as a way to abstract future values, or values that depend on something the user will do later, specifically Yehuda Katz's <a href=\"https:\/\/github.com\/tildeio\/rsvp.js\"><code>rsvp.js<\/code><\/a>, and came across <a href=\"http:\/\/domenic.me\/2012\/10\/14\/youre-missing-the-point-of-promises\/\">Domenic Denicola's <cite>You're Missing the Point of Promises<\/cite><\/a>, which got me looking at <a href=\"http:\/\/osteele.com\/posts\/2008\/04\/minimizing-code-paths-in-asychronous-code\">Oliver Steele's <cite>Minimizing Code Paths in Asychronous Code<\/cite><\/a>. Now I have another consideration in my code that I never thought about before.<\/p>\r\n<!--more-->\r\n<p>Javascript is <em>single-threaded<\/em> (see <a href=\"http:\/\/ejohn.org\/blog\/how-javascript-timers-work\/\">John Resig's article<\/a> and <a href=\"http:\/\/dev.opera.com\/articles\/view\/timing-and-synchronization-in-javascript\/\">Olav Kj\u00e6r's<\/a>). That means that we generally don't have to worry about the concurrency issues that plague languages with threading (I remember trying to understand <a href=\"http:\/\/www.amazon.com\/Concurrent-Programming-Java%C2%BF-Principles-Pattern\/dp\/0201310090\/\">Java's <code>Thread<\/code>s)<\/a>. However, it means that Javascript fakes concurrency with what we used to call when programming the original Macintosh <a href=\"http:\/\/everything2.com\/title\/Cooperative+multitasking\">\"cooperative multitasking\"<\/a>: one bit of code (call it a \"code unit\" in the dev.opera's terms) runs until it is done, then lets the next bit of code run. The programmer has to be sure that each code unit is small enough not to delay any other code, especially code that reacts to user input.<\/p>\r\n<p>Javascript makes it look like multiple things are going on concurrently by using an event loop. There's a queue of code units, and every user event like a mouse click, or timer event, or AJAX response, puts its handler onto the queue. The Javascript interpreter just runs each code unit in turn. Note that the event generators themselves <em>are<\/em> run on separate threads; the event queue is building up while the current code is running. It's just that none of the handlers get run concurrently.<\/p>\r\n<p>Putting a code unit on the queue is called <em>asynchronous<\/em> (meaning \"not coordinated in time\"), as opposed to normal function calls which interrupt the flow of code then return, which is called <em>synchronous<\/em>. \r\nOne other consequence of the separate code units is that exceptions stop at each code unit; they don't interrupt the event loop itself. So:<\/p>\r\n<pre><code class=\"language-html\" >&lt;script&gt;\r\nconsole.log(1);\r\nthrow('a');\r\nconsole.log(2);\r\n&lt;\/script&gt;\r\n&lt;script&gt;\r\nconsole.log(3);\r\n&lt;\/script&gt;<\/code><\/pre>\r\n<p>displays (in Chrome; browsers may differ in how they word uncaught exceptions and when those are displayed):<\/p>\r\n<pre>1\r\nUncaught a\r\n3<\/pre>\r\n<p>Note that <code class=\"language-javascript\" >console.log(3)<\/code> still runs; each <code class=\"language-html\" >&lt;script&gt;<\/code> is its own code unit.<\/p>\r\n\r\nThe fact that asynchronous code is run sequentially means that:<\/p>\r\n<pre><code class=\"language-html\" >&lt;script&gt;\r\nconsole.log(1);\r\nsetTimeout(function() {\r\n\tconsole.log(2);\r\n\tthrow('a');\r\n}, 0);\r\nconsole.log(3);\r\nthrow('b');\r\nconsole.log(4);\r\n&lt;\/script&gt;<\/code><\/pre>\r\n<p>displays:<\/p>\r\n<pre>1\r\n3\r\nUncaught b\r\n2\r\nUncaught a <\/pre>\r\n<p>The <code class=\"language-javascript\" >setTimeout<\/code> is a separate code unit put on the queue immediately (after \"delay\" of 0 ms) but, even if the current code takes a long time, will never run until after the current code is done and <code class=\"language-javascript\" >console.log(3)<\/code> is displayed. Note that the thrown exceptions only interrupt the code unit running at that time.<\/p>\r\n\r\n<p>One subtlety is that simple busy waiting (which is usually a bad idea anyway) never works:<\/p>\r\n<pre><code class=\"language-html\" >&lt;script&gt;\r\nconsole.log(1);\r\nvar done = false;\r\nsetTimeout(function() {\r\n\tconsole.log(2);\r\n\tdone = true;\r\n}, 10);\r\nconsole.log(3);\r\nfor (;;){\r\n\tif (done){\r\n\t\tconsole.log('done');\r\n\t\tbreak;\r\n\t}\r\n}\r\nconsole.log(4);\r\n&lt;\/script&gt;<\/code><\/pre>\r\n<p>displays<\/p>\r\n<pre>1\r\n3<\/pre>\r\n<p>then waits forever, even though the 10 ms has passed and the <code class=\"language-javascript\" >setTimeout<\/code> handler has been placed on the queue. Firefox detects the infinite loop and eventually gives the \"busy script\" alert; Chrome just waits until you kill it.<\/p>\r\n\r\n<p>I think we were all burned when first learning AJAX with:<\/p>\r\n<pre><code class=\"language-html\" >&lt;script&gt;\r\n\r\nvar data = undefined;\r\n\r\nfunction get(url){\r\n\tvar request = new XMLHttpRequest();\r\n\trequest.open(\"GET\", url, true);\r\n\trequest.onload = function(){\r\n\t\tdata = request.responseText;\r\n\t}\r\n\trequest.send();\r\n}\r\n\r\nget('generate.php');\r\nconsole.log(data);\r\n&lt;\/script&gt;<\/code><\/pre>\r\n<p>And, no matter how long it was since the <code class=\"language-javascript\" >XMLHttpRequest<\/code> was sent, <code class=\"language-javascript\" >data<\/code> was always <code class=\"language-javascript\" >undefined<\/code>. The <code class=\"language-javascript\" >onload<\/code> function is run asynchronously. So now we know to use <a href=\"http:\/\/en.wikipedia.org\/wiki\/Continuation-passing_style\">continuation-passing style<\/a> (known in the Javascript world as \"callbacks\"):<\/p>\r\n<pre><code class=\"language-html\" >&lt;script&gt;\r\n\r\nfunction get(url, callback){\r\n\tvar request = new XMLHttpRequest();\r\n\trequest.open(\"GET\", url, true);\r\n\trequest.onload = function(){\r\n\t\tcallback(request.responseText);\r\n\t}\r\n\trequest.send();\r\n}\r\n\r\nget('generate.php', function(data){\r\n\tconsole.log(data);\r\n});\r\nconsole.log(1)\r\n&lt;\/script&gt;<\/code><\/pre>\r\n<p>Which works correctly, but the <code class=\"language-javascript\" >console.log(data)<\/code> is asynchonous; the <code class=\"language-javascript\" >1<\/code> is displayed before the data, again, no matter how fast the <code class=\"language-javascript\" >XMLHttpRequest<\/code> is or how slow our code is.<\/p>\r\n<p>The subtle bug-inducing subtlety is when we the code might be asynchronous or synchronous. For instance, we use a cache for the AJAX data:<\/p>\r\n<pre><code class=\"language-html\" >&lt;script&gt;\r\nvar data;\r\n\r\nvar cache;\r\nfunction getwithcache(url, callback){\r\n\tif (cache !== undefined) return callback('cached data');\r\n\r\n\tvar request = new XMLHttpRequest();\r\n\trequest.open(\"GET\", url, true);\r\n\trequest.onload = function(){\r\n\t\tcache = request.responseText;\r\n\t\tcallback(request.responseText);\r\n\t}\r\n\trequest.send();\r\n}\r\n\r\ngetwithcache('generate.php', function(data){\r\n\t\tdoSomething(data);\r\n});\r\nconsole.log(data);\r\n&lt;\/script&gt;<\/code><\/pre>\r\n<p>The first time <code class=\"language-javascript\" >getwithcache<\/code> runs, <code class=\"language-javascript\" >callback<\/code> runs asynchronously, so line 20 displays <code class=\"language-javascript\" >undefined<\/code>.\r\n<p>If the cache has been defined (after a successful <code class=\"language-javascript\" >XMLHttpRequest<\/code> on line 11), then line 6 runs the callback synchronously, meaning that the <code class=\"language-javascript\" >console.log(data)<\/code> on line 20 displays that data.<\/p>\r\n<p>In addition, if the callback throws an exception, in the first case that will not interrupt the rest of the program but in the second case it will.<\/p>\r\n<p>This unpredictability may make for bugs that are hard to track down, since they depend on apparently random factors. Steele's advice is to make sure that if code <em>might<\/em> run asynchronously, then it <em>always<\/em> runs asynchronously. Promise\/A+ guarantees that, at the cost of slower code (the handlers never run immediately).<\/p>\r\n\r\n<p>I don't know that I've ever been bitten by this bug but one place where it may come up is in event handling. Even though event handlers are run asynchronously, triggering them directly is <em>synchronous<\/em> as far as I can tell:<\/p>\r\n<pre><code class=\"language-html\" >&lt;button&gt;Click&lt;\/button&gt;\r\n&lt;script&gt;\r\nvar button = document.querySelector('button');\r\nbutton.addEventListener('click', function(){\r\n\tconsole.log('in click handler');\r\n});\r\n\r\nconsole.log(1);\r\nbutton.dispatchEvent(new CustomEvent('click'));\r\nconsole.log(2);\r\n&lt;\/script&gt;<\/code><\/pre>\r\n<p>displays<\/p>\r\n<pre>1\r\nin click handler\r\n2 <\/pre>\r\n<p>even though it ought to be <code>1<\/code> then <code>2<\/code> then <code>in click handler<\/code>  if it were asynchronous. It does have some exception-catching protection, since throwing an exception in the event handler does not bubble up to the enclosing code. Using jQuery's <code class=\"language-javascript\" >trigger<\/code> is also synchronous (but doesn't stop the exception).<\/p>\r\n<p>This means that a given handler may be called synchronously or asynchronously, depending on whether the event was generated by the user interface or was synthetic. Just one more thing to keep in mind in our ever-more-complicated Javascript applications.<\/p>","protected":false},"excerpt":{"rendered":"I've been looking at Promise\/A+ as a way to abstract future values, or values that depend on something the user will do later, specifically Yehuda Katz's rsvp.js, and came across Domenic Denicola's You're Missing the Point of Promises, which got me looking at Oliver Steele's Minimizing Code Paths in Asychronous Code. Now I have another [&hellip;]","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[10],"tags":[],"_links":{"self":[{"href":"https:\/\/bililite.com\/blog\/wp-json\/wp\/v2\/posts\/3054"}],"collection":[{"href":"https:\/\/bililite.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/bililite.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/bililite.com\/blog\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/bililite.com\/blog\/wp-json\/wp\/v2\/comments?post=3054"}],"version-history":[{"count":8,"href":"https:\/\/bililite.com\/blog\/wp-json\/wp\/v2\/posts\/3054\/revisions"}],"predecessor-version":[{"id":3062,"href":"https:\/\/bililite.com\/blog\/wp-json\/wp\/v2\/posts\/3054\/revisions\/3062"}],"wp:attachment":[{"href":"https:\/\/bililite.com\/blog\/wp-json\/wp\/v2\/media?parent=3054"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/bililite.com\/blog\/wp-json\/wp\/v2\/categories?post=3054"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/bililite.com\/blog\/wp-json\/wp\/v2\/tags?post=3054"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}