Loading repository data…
Loading repository data…
eoinkelly / repository
A deep dive into the Ember JS runloop.
A transparent discovery signal based on current public GitHub metadata.
This score does not audit code, security, maintainers, documentation quality, or suitability. Verify the repository and its current documentation before adoption.
by Eoin Kelly

If you spot any of the (sadly inevitable) errors you would be doing me a great favour by opening an issue :-).
You can get started with Ember application development without understanding the runloop. However at some point you will want to dig in and understand it properly so you can use it skillfully. It is my sincere hope that this handbook can be your guide.
We are about to take a deep dive into the Ember.js runloop. Together we will answer these questions:
This is not reference documentation - the Ember API docs have that nicely covered. This isn't even the "I'm an experienced dev, just give me the concepts in a succinct way" documentation - the Official Ember Run-loop guide has that covered. This is a longer, more detailed look at the runloop.
As you learn more about the Ember runloop you will come to understand that, well, it just isn't very loopish. The name is a bit unfortunate as it implies that there is a single instance of the runloop sitting somewhere in memory looping endlessly running things. As we will see soon this is not true.
In alternate universes the runloop might have been named:
OK some of those names are really terrible (except Runelope of course, that one is pure gold and should be immediately pushed to Ember master). Naming is a hard problem and hindsight is 20/20. The runloop is what we have so that is what we will call it but try not to infer too much about its action from its name.
On our journey to understand the runloop we must first understand the environment it lives in and the problems it is trying to solve. Lets set the scene by refreshing a few fundamentals about how Javascript runs. (If you are an experienced Javascript developer you may want to just skip this part)
Our story begins with when the browser sends a request to the server and the server sends HTML back as a response.
The browser then parses this HTML response. Every time it finds a script it executes it immediately(*) Lets call this the setup phase. This setup phase happens well before the user sees any content or gets a chance to interact with the DOM. Once a script is finished executing the browser never runs it again.
(*) Things like defer tweak this somewhat but this is a useful simplification.
The browser does most of its communication with Javascript by sending "events". Usually these are created in response to some action from one of:
mousemove)load)However there are a few events that the browser generates itself to tell
Javascript about some important event in the lifecycle of the page. The most
widely used of these is DOMContentLoaded which tells Javascript that the HTML
has been fully parsed and the DOM (the memory structure the browser builds by
parsing the HTML) is complete. This is significant for Javascript because it
does most of its setup work in response to this event.
Javascript is lazy but well prepared! During the setup phase, Javascript prepared its work space (or mise en place if you prefer) - it created the objects it would now need to respond to orders (events) from the browser and also told the browser in detail what events it cares about e.g.
Hey browser, wake me up and run this function I'm giving you whenever the user clicks on an element with an id attribute of
do-stuff.
The description above makes it look like the browser is the one giving all the orders but the browser is a team player and has a few things it can do to help Javascript get the job done:
Timers. Javascript can use the browser like an alarm clock:
Javascript: Hey browser, wake me up and run this function I'm giving you in 5 seconds please.
Talking to other systems. If Javascript needs to send or receive data to other computers it asks the browser to do it:
Javascript: Hey browser, I want to get whatever data is at
http://foo.com/things.jsonplease.
Browser: Sure thing but it might take a while. What do you want me to do when it comes back?
Javascript: I have two functions ready to go (one for a successful data fetch and one for a failure) so just wake me up and run the appropriate one when you finish.
Browser: cool.
We usually refer to this talking to other systems stuff as Web APIs e.g.
Javascript can use these services of the browser both during the setup phase and afterwards. For example part of the Javascript response to a "click" event on a certain element might be to retrieve some data from the network and also schedule a timer to do some future work.
We now know enough to see the pattern of how javascript and the browser interact and to understand the two phases:
A solid understanding of this stuff is required to understand the runloop so if you are unclear about any of this and want to dig a little deeper I recommend a wonderful video by Philip Roberts at JSConf EU that goes into the Javascript event loop in more detail. It is a short watch and includes a few "aha!"-inducing diagrams.
Since Ember is Javascript we already know quite a bit about how Ember works:
DOMContentLoaded event is significant in the life of an Ember app. It tells
Ember that it now has a full DOM to play with. Ember will do most of its "setup work"
(registering for event listeners etc.) in response to this event.setTimeout)How does your Ember application relate to the Ember framework? The machinery for responding to events is part of Ember framework itself but it does not have a meaningful response without your application code.
For example if the user is on /#/blog/posts and clicks a link to go to
/#/authors/shelly the Ember framework will receive the click event but it
won't be able to do anything meaningful with it without:
BlogRoute, PostsRoute, AuthorsRouteThe Ember docs have a list of events Ember listens for by default which I have repeated here:
These are the entry points into our code. Whenever Ember code runs after the setup phase, it is in response to an event from this list.
This is a good resource for refreshing your understanding of how DOM events work. To get the most of the following discussion you should be familiar with how the browser propagates events and what the phrases "capturing phase" and "bubbling phase" mean.
Ember registers listeners for these events similarly to how we might do it ourselves with jQuery i.e.
<body>. If you specify a rootElement then that will be used instead.The pattern of how Javascript (Ember) works is periods of intense activity in response to some event followed by idleness until the next event happens. Lets dig a little deeper into these periods of intense activity.
We already know that the first code to get run in response to an event is the listener function that Ember registered with the browser. What happens after that?
Lets consider some code from an imaginary simple Javascript app:
http://jsbin.com/diyuj/5/edit?html,js,console,output
This code manages the "Mark all completed" button in the UI.
Click the button a few times and notice the console output. Notice that there are some patterns to the tasks performed:
and that the do work as you find it approach that this app takes causes these different types of work to be interleaved.
The code in this app is obviously very incomplete and I'm sure you can see many ways it could be improved. However there are some problems that might not be obvious at first, problems that you will only start to notice when the app grows in complexity. To understand these lets look at what it is not doing: