Tony
Tony

Reputation: 38361

What does this.async() do in JavaScript

Kept on seeing this pattern in code, but couldn't find any reference to it in google or SO, strange. Can someone point me to reference for this.async() function?

  var done = this.async();
  // ...
  $.get(path, function(contents) { // or some other function with callback
    // ...
    done(JST[path] = tmpl);
  })

Upvotes: 12

Views: 7023

Answers (3)

Aziel
Aziel

Reputation: 331

var done = this.async() is a pattern used in Grunt to help perform asynchronous functions within a Task.

You need to invoke done() or done(returnValues) to tell Grunt the task is complete (after your chain of asynchronous tasks).

Read more about it: https://gruntjs.com/inside-tasks#inside-all-tasks

Upvotes: 1

Brian Park
Brian Park

Reputation: 2577

var done = this.async() and done(blah) is a clever trick to return a value fetched from asynchronous call (e.g. $.get) within a synchronous function.

Let's see an example:

var getText = function() {
  return "hello";
};
var text = getText();

It's a pretty straightforward function call so no puzzle here. However, what if you need to fetch the text asynchronously in getText() function?

var getText = function() {
  return $.get('<some-url>', function(text) {
    return text;
  });  // ??????
};

call to getText() doesn't return the text you want to get. It returns jquery's promise object.

So how do we make getText() return the text it gets from $.get() call?

var getText = function() {
  var done = this.async();
  $.get('<some-url>', function(text) {
    done(text);
  });
};
var text = getText();  // you get the expected text

Magic, right?

I don't know the inner-working of this.async() call yet. I don't know if there is a library provides that function, but you can see that Backbone.LayoutManager uses this trick https://github.com/tbranyen/backbone.layoutmanager/blob/master/backbone.layoutmanager.js (search for this.async).

Also, Tim Branyen (the author of backbone layoutmanager) briefly talks about it in his video tutorial (http://vimeo.com/32765088 around 14:00 - 15:00). In the video, Tim says Ben Alman came up with that trick. Take a look at this as well https://github.com/cowboy/javascript-sync-async-foreach

I think it's a pretty neat trick to mix async and sync functions.

Cheers,

Upvotes: 20

Tomasz Nurkiewicz
Tomasz Nurkiewicz

Reputation: 340713

It is a way to work around the problem of this escaping inside callback. Without this extra reference the code would look like this:

$.get(path, function(contents) { // or some other function with callback
  //Wrong! `this` might no longer point to your object
  this.done(JST[path] = tmpl);
})

Unfortunately! this inside response callback is not the same as this outside of it. In fact it can be anything, depending on what $.get (calling the callback using) decides it to be. Most of the people use extra reference named that for the same purpose:

var that = this;
// ...
$.get(path, function(contents) { // or some other function with callback
  // ...
  that.async(JST[path] = tmpl);
})

This pattern also seems reasonable and readable.

Oh, and if you are curious about this syntax:

done(JST[path] = tmpl)

This is an assignment used as an expression. The value of assignment is the right-hand side, so this code is equivalent to:

JST[path] = tmpl;
done(tmpl);

Upvotes: -3

Related Questions