Returning promises
Returning promises
If you are creating a long running function, you can return a
promise
, allowing the caller to be alerted to your operations status, or when it completes. You return, and manage, a promise
by creating an instance Deferred
.Deferred
Deferred
and promise
seem very similar, and they are. The difference between the two is who uses which. Deferred
is used to create, and manage, a promise
object. A promise
object is returned by a long running operation, and only allows you to register event handlers.
To put this another way,
Deferred
is the server side. When create a long running function that will be called by other developers, you'll use Deferred
to return a promise
. You'll use the Deferred
object to update clients when your function completes (or you want to send a progress signal).
Continuing the analogy,
promise
is the client side. When you call a long running function, it will return a promise
. You will use the promise
to be alerted, and execute code, when that long running function completes (or sends a progress signal).Using Deferred
When to use Deferred
If you are creating a function that may take a long time to execute, it's best to return a
promise
. This makes it easier for developers who call your function, as they can use the promise
events.
One nice thing about jQuery is the developers of the API follow their own best practices. As a result, if you execute an operation, such as an Ajax call, the function will return a
promise
. If you are creating a function that will be wrapping such a call, you can simply return the promise
returned by the function.
For example, consider the following jQuery. We create a function that calls
slideToggle
. slideToggle
can take a couple of seconds to execute, depending on how long you tell the operation to take. As a result, it returns a promise
, as we saw in an earlier section. Because slideToggle
returns a promise
object already, we can just use that, rather than creating a Deferred
object on our own.function displayMenu() {
// just return the promise object
return $('#menu').slideToggle(500);
}
However, if we are creating a function that will take an unusual amount of time, say one that will be working with graphics, we need will want to use
Deffered
to return a promise
to the caller.Breaking down using Deferred
The basic steps are as follows.
- Create an instance of deferred:
var deferred = $.Deferred();
- Start your asynchronous operation, typically using a worker
- Add the appropriate code to detect success and send the success signal:
deferred.resolve()
- Add the appropriate code to detect failure and send the failure signal:
deferred.reject()
- Return the promise:
return deferred.promise();
function beginProcessing() {
// Create deferred object & make sure it's going to be in scope
var deferred = new $.Deferred();
// Create our worker (just like before)
var worker = new Worker('./Scripts/deferred.js');
// Register the message event handler
worker.addEventListener('message', function (e) {
// simple messaging - if the worker is ready it'll send a message with READY as the text
if (e.data === 'READY') {
// No UI code
// Progress notification
deferred.notify('Worker started');
} else if(e.data === 'COMPLETED') {
// processing is done
// No UI code
// Completed notification
deferred.resolve('Worker completed');
worker.terminate();
}
});
return deferred.promise();
}
No comments:
Post a Comment