|jQuery 3 - Implementing Promises|
|Written by Ian Elliot|
|Monday, 29 May 2017|
Page 1 of 3
Available as a Book:
Buy from Amazon.
Events, Async & AJAX
buy from Amazon
After learning how to use or consume promises the next step is add support for promises to asynchronous functions and how to work with them to create new promise features.
The jQuery Deferred Object
The big problem initially in implementing promises was that it was essential to provide functions so that the code that was using the promise to signal when it was finished could change the state of the promise, but code that was consuming the promise using then and that catch function was unable to change the promise's state.
only the code that created the promise should be able to set the promise's state.
The earliest solution to this problem of keeping the internal state private was to use a two-object solution. A deferred object was used by the promise creator to manage the promise. The deferred had the necessary functions to resolve and reject the promise and the promise had all of the functions the consumer needed, like then. In practice it was better to have the deferred object also having all of the functions that the promise had and so the deferred looked like a "super" promise object. In retrospect this is probably a mistake as it results in a confusion between what the deferred is and what it is used for. If you wanted to you could pass the deferred object to the user rather than the promise and this would allow them to change the internal state.
You create a deferred using:
The most important deferred methods are:
In most cases you will use resolve or reject.
If you call a deferred resolve method then the promise associated with it is fulfilled. That is, any onComplete handler attached using then will be called with the same arguments.
sets the promises state to fulfilled which results in any then onComplete handler to be called with myValue as a parameter.
The reject method works in the same way but it causes the promise to be rejected.
sets the promise's state to rejected and any failure callback is called with myReason as a parameter.
The functions resolveWith and rejectWith work in the same way as resolve and reject, but the first argument sets the context, i.e. this in the calls of the onSucess or onReject handlers. So for example:
will set the promise's state to fulfilled and call any onSucess handler with myValue as a parameter and with this set to myButton. It isn't often that you need resolveWith or rejectWith, but they can make using object methods as promise handlers possible.
The only other deferred function that is important is promise which returns a reference to the promise that the deferred is associated with.
Using A Deferred
One of the problems of using Deferreds is seeing how they are actually used to implement an asynchronous function that returns and manages a promise. The best way of finding out is by way of a simple example.
The timeOut function has already been introduced in earlier chapters as a way of turning a synchronous function into an asynchronous one. It can also be used to delay the running of a function by a specified time:
will run the specified function after time milliseconds have past. We can turn this into a delay function that returns a promise that resolves after the specified time.
All we have to do is create a deferred:
Next we start the asynchronous operation off and arrange that when it is finished it sets the Deferred's state to fulfilled or rejected. In this case it is difficult to see how the timer could fail and so we just need to fulfill the Deferred when the time is up:
Now all we have to do is return the promise so that the client code can use it:
The complete function is:
If this is your first promise-returning function you might think it is strange - where is the function that is run when the delay is up?
The whole point is that this function will delay running any function the client code associates with it using then and it will run multiple functions if you want it to. For example, to use it you might write:
As delay returns a promise, you can use any of the usual methods to schedule other functions depending on its state - primarily then and catch, but this is trickier than it might seem, as described later.
|Last Updated ( Monday, 29 May 2017 )|