Sessions is temporarily moving to YouTube, check out all our new videos here.

Ember Concurrency

Sam deMaeyer speaking at Ember London in April, 2017
Great talks, fired to your inbox 👌
No junk, no spam, just great talks. Unsubscribe any time.

About this talk

Watch what makes ember concurrency so good, plus some examples to demonstrate how you can use it in your applications.


Sam: Hello, I'm Sam. This is me, gently touching the Golden Gate bridge two weeks ago, after the conf. About just over a year ago [inaudible 00:00:13] Alex and he wanted to create something revolutionary in the ember world and as has been proven revolutionary in javascript at all. Because there were some things broken in javascript in general, [00:00:30] so therefore also on ember which he wanted to address. This guy was Alex. This is him. I just use this picture because he used it in his talk, but if you would see him in real life, it would be more like this. What is ember-concurrency? Ember-concurrency is an ember addon that enables you to write concise, worry free, cancelable, [00:01:00] restartable and asynchronous tasks. Yeah sorry. Basically what I said before was there are some things broken in javascript therefore ember. It should be easy to write cancelable and ... I'm sorry I'm struggling with this word ... Asynchronous operations. This is especially hard with promises as most people do now. [00:01:30] It should be easy to prevent to or more asynchronous operations from happening at the same time. Again, promises and observables are really hard to do this. We want to minimise boilerplate and maximise implicit state and finally the API should feel familiar and at home for ember developers. This is why ember-concurrency was created. Let's go to [00:02:00] a few quick examples. Here we have a simple button and when you click it again it will cancel the count and start over again. It's a simple implementation with task and time out, we will go into details after this. Ember-concurrency comes with some built in standard functionality, so the default one, so this is the default behaviour, [00:02:30] when you do task perform when you click on it like the animation shows you, task will overlap the next one. This is just default behaviour, this might be what you need, might not be. Therefore restartable. Whenever you click it will cancel the previous running task and it will start a new one. Every time you click it as many times as you want it will start a new task and cancel the previous one. Drop [00:03:00] is actually the other way around. You click on a button, you click it many times after and the task will not start again and will just drop the task you are trying to start until the initial task was finished and finally just want to have a quick or one more, the keep last which is really interesting so it behaves [inaudible 00:03:22] but it will keep the most recent [inaudible 00:03:27] task to [00:03:30] perform. It will drop all the other tasks. What I want you to talk to you about today is more of an actual use case and what I want to explain is something that is probably used in many cases but especially here in alpha site today, I talked to one of the developers, Will, and this is a use case that actually happens here. Imagine that you have a team of people working [00:04:00] and there is a pop up in your system and your pop has a form. Your form loads all the data, which is already there, it's not a create form, it's an update form. You have a button which will save the data. People can just type in whatever they want and whatever they need, click on save and everything gets saved. Then, because this application might need more revisions, you want to see what you did, you want to save something quickly, wait [00:04:30] to save something else, you don't want to close the pop up immediately. When the pop up closes, there is a separate button to close the pop up. That means you click save. So you fill in your form, you click save. Maybe you want to fill in something else, you want to change something. You click save again and once you're ready you exit. What happens often is you save exit. Save exit because it’s the last one you did. The problem is if this pop up is a component, the component gets destroyed [00:05:00] and the action that you did, the query to the database might have succeeded, might have failed. If you're too fast it would even have cancelled the request. Ember-concurrency is perfect for this use case. Let's start with importing ember-concurrency, so we're gonna import task from ember-concurrency, right here and here you can see our save form [00:05:30] task. The save form task will only save the model, that's it. As you can see there is a restartable attached on the end, so that means if you save something, quickly, quickly type something else in a input field and save it again. It will cancel the first save and only save the last one. As I said before there is a separate button. In our case it will be a button to close the application. This close button also has a task on it, which [00:06:00] we'll only check if your only has dirty attributes, which means you have changed something in your text fields. If there is no changes with the previous save, then it will just transition out and destroy the component. If there are things that have changed, which can mean two things. Either the user has changed something and he wants to save it again, [00:06:30] or it can mean it was still saving because your checking model has dirty attributes, but because the model has a yield function and returns the model to save the results, we don't know if somebody changed something or the request hasn't finished yet. IN this case, we're just gonna call the task, the save form task, calling it like this, this dot save form task is [00:07:00] a task instance and on this task instance we can use some built in functionality. In this case we're gonna use is running. Is running is a bulletin, true or false, is running means it's still running, there is no result came back from the server. In this case if there are dirty attributes, if there is a change it might be that somebody will try to save something again or that the task is still running, so what we are gonna do is, if [00:07:30] is still running, we're gonna call the task instance again and we're gonna check the last attribute. Last is not a value. You can get the value of last, which is fine if you just want to check the value. That will be save form task dot last dot value and then you will have the return value from the task. Last is actually the promise. In this case, very useful, we had a promise, we can yield it. We can say, "Wait to close this popup [00:08:00] until there was a response from the server.", the last response from the server in this case a restartable has been ... All the others has been destroyed anyway, but ... Okay there we go. Speaker 2: Now you can see it. Sam: [00:08:30] Yeah. So sorry I talk too much. In this case, we're just gonna wait for the lase promise to be resolved and in the "L" statement we're just gonna set a sure reminder, which is something like a reminder saying, " You have changed things, because we know that the model has changed and the task has finished.", so we're just gonna remind the user and say, "You tried to save something, but you changed something, [00:09:00] do you want to go ahead with saving?", this was the original use case. I wanted to point out as well that you can do some animation with ember-concurrency, so I change it a little bit. Same example, we're gonna import time out right here and as you can see, here we have changed to set the variable to ... Actually call another task. And this task will yield a time out. [00:09:30] A timeout imported from ember-concurrency which basically means, "Wait until the value passed in milliseconds. Wait 3,000 milliseconds.", so you're gonna wait 3 seconds to finish the task. This means there is is animation, maybe a class or however you want to do it or something displaced on your screed for three seconds. In our template it will be something like [00:10:00] this. You have a bunch of input fields, you have the form pop up model, which is just a form, a component which will be destroyed whenever it stops rendering. YOUr button, you have the primary button which is the save button and then you have an exit button, which is the close task one. Here we have, if the task is running, which we saw before, which we also can use in the template [00:10:30] as long as it's running we're gonna add a glass shake. In our case is gonna have a glass shake for three seconds and then remove it. And there we go. So basically what I wanted to prove with this is for animations especially you can, like I did in the past I used ember run, which is perfectly fine you can use it, but it's a little bit overkill for animations and this [00:11:00] is really nice implementations to you use animations, just adding a glass with some library or how ever you want to do it yourself. Obviously this wouldn't do anything because you would just shake the save button and you don't prompt the message, but that just wanted to change a little bit. Anyway, for more information there are lots of resources on ember-concurrency, the guy who written it has amazing website, [00:11:30] all the screenshots that I taken were from the website. Go ahead, visit it and check it out and if you're not using it try it out, because it's amazing. I can say in [inaudible 00:11:40] homework, we are using it right now and it's made a big, big difference. Thank you.