Using jQuery Deferred Objects and Promises Instead of Callbacks
Using jQuery Deferred Objects and Promises Instead of Callbacks
In a previous post jQuery Tip #7 – Consolidating jQuery Ajax Calls I talked about how Ajax calls can be consolidated into a JavaScript object to promote re-use and simplify maintenance. In that post I showed how the Revealing Module Pattern can be used to provide a more structured approach and how a callback can be passed into functions within the object. Once individual Ajax calls complete the callback can be invoked so that the caller is able to access the returned data.
The following code shows an example of a simple object named dataService that follows the Revealing Module Pattern and has several Ajax functions in it. Note that each function accepts a callback as a parameter and that the callback is invoked to return the data to the caller.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 | var dataService = new function () { var serviceBase = '/DataService/', getAccount = function (acctNumber, callback) { $.getJSON(serviceBase + 'GetAccount', { acctNumber: acctNumber }, function (data) { callback(data); }); }, getMarketIndexes = function (callback) { $.getJSON(serviceBase + 'GetMarketIndexes', function (data) { callback(data); }); }, getQuote = function (sym, callback) { $.getJSON(serviceBase + 'GetQuote', { symbol: sym }, function (data) { callback(data); }); }, getTickerQuotes = function (callback) { $.getJSON(serviceBase + 'GetTickerQuotes', function (data) { callback(data); }); }; return { getAccount: getAccount, getMarketIndexes: getMarketIndexes, getQuote: getQuote, getTickerQuotes: getTickerQuotes }; } (); |
Although this code works fine, by forcing a callback to be passed as a parameter the parameter signature of each function is polluted somewhat. Even worse, no error callback is defined so if an error occurs the caller of the dataService object may be left in the dark which will more than likely leave the user in the dark as well if something goes wrong.
JavaScript libraries such as jQuery, Q.js, and others support the concept of a deferred object and allow access to a promise. For example, jQuery's getJSON()function automatically returns a deferred object/promise to callers. That means that the caller receives an object immediately after calling an asynchronous Ajax function and can use it to handle the success and error callback functionality themselves rather than relying on the function to invoke a callback as in the previous code.
The following code shows an improved version of the callback code shown earlier. Notice that no callback parameter is passed into the different functions and that the result of the getJSON() call (a deferred object) is returned instead.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | var dataService = new function () { var serviceBase = '/api/dataService/', getAccount = function(acctNumber) { return $.getJSON(serviceBase + 'account', { acctNumber: acctNumber }); }, getMarketIndexes = function() { return $.getJSON(serviceBase + 'marketIndices'); }, getQuote = function(sym) { return $.getJSON(serviceBase + 'quote', { symbol: sym }); }, getTickerQuotes = function() { return $.getJSON(serviceBase + 'tickerQuotes'); }; return { getAccount: getAccount, getMarketIndexes: getMarketIndexes, getQuote: getQuote, getTickerQuotes: getTickerQuotes }; } (); |
Consumers of the dataService object can now call functions, handle the deferred object that's returned and then wire up success and error functions. An example of doing that is shown next:
1 2 | dataService.getMarketIndexes().done(renderMarketTiles); dataService.getAccount().done(accountNumber); |
These two calls handle the success callback but don't handle errors. To do that you can chain a fail() function onto the previous code as shown next:
1 2 3 4 5 | dataService.getMarketIndexes().done(renderMarketTiles) .fail(handleError); dataService.getAccount().done(accountNumber) .fail(handleError); |
By using deferred objects and promises you can handle asynchronous callbacks in a more standardized way and provide a better to process success and error situations. You can also clean up the parameter signature of any Ajax methods that you may call and re-use throughout an application.
Enjoy!
Dan Wahlin Microsoft MVP
.NET Developer Instructor
Interface Technical Training
You May Also Like
Cable Testers and How to Use them in Network Environments
0 668 1This content is from our CompTIA Network + Video Certification Training Course. Start training today! In this video, CompTIA Network + instructor Rick Trader demonstrates how to use cable testers in network environments. Let’s look at some tools that we can use to test our different cables in our environment. Cable Testers Properly Wired Connectivity … Continue reading Cable Testers and How to Use them in Network Environments
How to Build in a PSMethod to your PowerShell Code
0 68 0In this video, PowerShell instructor Jason Yoder shows how to add Methods (PSMethod) to your code using free software that’s added into the PSObject. For instructor-led PowerShell courses, see our course schedule. Microsoft Windows PowerShell Training Download the Building Methods PowerShell script</a> used in this video. <# ╔══════════════════════════════════════════════════════════════════════════════╗ ║ ║ ║ Building Methods ║ ╟──────────────────────────────────────────────────────────────────────────────╢ … Continue reading How to Build in a PSMethod to your PowerShell Code
How to use the PowerShell Script Analyzer to Clean Up Your Code
0 1229 2In this video, PowerShell instructor Jason Yoder demonstrates how you can use the PowerShell Script Analyzer to help you format your code to best-practices. For instructor-led PowerShell training classes, see our course schedule: Microsoft Windows PowerShell Training Download the PowerShell Analyzer scripts used in this video. <# ╔══════════════════════════════════════════════════════════════════════════════╗ ║ ║ ║ PowerShell Script Analyzer ║ … Continue reading How to use the PowerShell Script Analyzer to Clean Up Your Code