24. Sequential Ajax (Sajax)
An Ajax pattern for handling multiple
asynchronous requests while maintaining
proper callback execution order.
25. Goals of Sequential Ajax (Sajax)
• Facilitate combination and manipulation of data from
multiple sources
• Speed loading of data, scripts, stylesheets using parallel
asynchronous HTTP requests
• Speed execution of callbacks by allowing them to fire as
soon as all previous data is available
• Fun
26. Three Flavors of Sajax
• Serial request / serial response
• Parallel request / random response
• Parallel request / serial response
60. Serial Request / Serial Response
// Request an article
$.getJSON('/article/1.json', function (article) {
// Request the related comments
$.getJSON('/article/1/comments.json', function (comments) {
// Join the data
article.comments = comments;
// Render the article and comments
render(article);
});
});
61. Serial Request /
Serial Response
• Pros
• Relatively readable
• Cons
• Slower
• Nested calls don’t
scale
62. Parallel Request / Random Response
var i = 0, n = 2, article, comments;
$.getJSON('/article/1.json', function (data) {
article = data;
if (++i == n) {
handleComplete();
}
});
$.getJSON('/article/1/comments.json', function (data) {
comments = data;
if (++i == n) {
handleComplete();
}
});
function handleComplete () {
article.comments = comments;
render(article);
}
66. Sexy is a jQuery plugin
A lightweight JavaScript library which provides parallel
request/serial response Sequential Ajax (Sajax) functionality
and a sleek facade to jQuery’s native Ajax methods.
67. Sexy is a standalone library
A lightweight JavaScript library which provides parallel
request/serial response Sequential Ajax (Sajax) functionality
and a sleek facade to jQuery’s native Ajax methods
JavaScript.
68. Sexy is a standalone library
A lightweight JavaScript library which provides parallel
request/serial response Sequential Ajax (Sajax) functionality
and a sleek facade to jQuery’s native Ajax methods
JavaScript (using jQuery’s native Ajax methods).
78. I WASN’T KIDDING!
If you are pregnant, have a serious heart
condition, or giggle uncontrollably at the word
“titillate”, you may want to hurry to Track A.
80. Sexy is Your Syntactic Sugar Mama
An expressive method for each supported data type:
html (url, callback)
json (url, callback)
jsonp (url, callback)
script / js (url, callback)
text (url, callback)
xml (url, callback)
style / css (url, callback)
81. Sexy is Patient
Requests can be deferred using an optional 2nd argument.
html (url, defer, callback)
json (url, defer, callback)
jsonp (url, defer, callback)
script / js (url, defer, callback)
text (url, defer, callback)
xml (url, defer, callback)
style / css (url, defer, callback)
82. Sexy is Flexible
Each method can also take a jQuery settings object.
html (settings)
json (settings)
jsonp (settings)
script / js (settings)
text (settings)
xml (settings)
style / css (settings)
83. callback (data, previous, next, status)
Each callback receives four arguments:
data response data of the current request
previous return value of the previous callback
next Ajax settings of the next request
status result status of the current request
111. var s = Sexy
.js('jquery.min.js')
.js('jquery.template.min.js')
.css('friends.css')
.text('friend.tpl')
.json('friends.json', function (data, tpl) {
// Send a new request for each friend (executed simultaneously)
$.each(data.friends, function (i, friend) {
s.json(friend.username + '.json', function (friend, friends) {
// Push onto the previously returned array
friends.push(friend);
// Until the last friend, return the augmented array to the next callback
if (i < data.friends.length - 1) {
return friends;
// When we reach the last friend, render the data and insert into the DOM
} else {
$.template(tpl, friends).appendTo('#friends');
}
});
});
// Instantiate the friends array
return [];
});
112. Known Issues
• Unable to detect error events for remote requests
• jsonp (remoteUrl)
• script (remoteUrl)
• style (remoteUrl)
• style (remoteUrl) fires the success callback even if the
request was unsuccessful (ie. 404)
113. Parallel Request / Serial Response
• Pros
• Faster
• Cleaner
• Prettier
• Cons
• Sexy.js adds
1.4Kb–4.6Kb to
your JavaScript
library
114. Parallel Request / Serial Response
• Pros
• Faster
• Cleaner
• Prettier
• Cons
• Sexy.js adds
1.4Kb–4.6Kb to
your JavaScript
library
115. Can’t get enough?
website http://sexyjs.com
slideshow http://www.slideshare.net/furf
download http://github.com/furf/Sexy
twitter @sexyjs or @furf
email furf@furf.com
feel free to be geeky as we go along, my code is available on github
Also, if you&#x2019;d like to read some hastily scribed documentation, i have a website at sexyjs.com, but i have to warn you ...
it&#x2019;s been deemed too risque for the workplace...
by this guy... if you think it&#x2019;s NSFW but still want to try it
i&#x2019;ve prepared another website for you
i&#x2019;ve prepared another website for you
it&#x2019;s even compatible with navigator 4.
okay... let me look at my notes for a second
okay... let me look at my notes for a second
OK. Let&#x2019;s begin. Some of you might remember me from jsconf.eu. For those that don&#x2019;t, my name is Dave Furfero. I&#x2019;m a UI Engineer at MLB.com, long-time JavaScripter, long-form improviser, and all-around lovable guy. I&#x2019;m known as furf all around the world and the Internets.
okay let&#x2019;s get started
I&#x2019;ve come to talk to you about your never-ending thirst for asynchronous data, some Sequential Ajax patterns for loading and combining your data, and a little library I wrote called Sexy which makes it so so simple.
I&#x2019;d guess that about 95% of the people in this room are working on the Internet&#x2019;s next killer app. I&#x2019;d also wager that 95% of those people are using Ajax to load data and that 95% of those people are loading data from more than one service. And I would venture that 95% of those people would like that data to interact in a meaningful way.
As we work with a larger number and greater variety of data sources, and we&#x2019;re no longer served by the one request/one callback paradigm, we need to evolve new patterns for dealing with the unpredictability of Ajax. Sequential Ajax helps you mix and mash asynchronous data from various sources, local and remote, with predictable results.
As we work with a larger number and greater variety of data sources, and we&#x2019;re no longer served by the one request/one callback paradigm, we need to evolve new patterns for dealing with the unpredictability of Ajax. Sequential Ajax helps you mix and mash asynchronous data from various sources, local and remote, with predictable results.
And Sexy? Sexy makes it look good. Damn good.
And Sexy? Sexy makes it look good. Damn good.
Sequential Ajax is any of a number of patterns for writing Ajax that allow you to fire multiple requests, receive the data, and hopefully before they are finished allow you to meaningfully manipulate that data
Sajax comes in three flavors. Two of them get the job done. One of them gets the job done Sexily
Let&#x2019;s say we fire off three asynchronous requests, the server or servers do their thing, and send back the data. In this scenario, our data returns in the specified order and we execute each callback as soon as its data is available ready. Even if the others have yet to return.
Let&#x2019;s say we fire off three asynchronous requests, the server or servers do their thing, and send back the data. In this scenario, our data returns in the specified order and we execute each callback as soon as its data is available ready. Even if the others have yet to return.
Let&#x2019;s say we fire off three asynchronous requests, the server or servers do their thing, and send back the data. In this scenario, our data returns in the specified order and we execute each callback as soon as its data is available ready. Even if the others have yet to return.
Let&#x2019;s say we fire off three asynchronous requests, the server or servers do their thing, and send back the data. In this scenario, our data returns in the specified order and we execute each callback as soon as its data is available ready. Even if the others have yet to return.
Let&#x2019;s say we fire off three asynchronous requests, the server or servers do their thing, and send back the data. In this scenario, our data returns in the specified order and we execute each callback as soon as its data is available ready. Even if the others have yet to return.
Let&#x2019;s say we fire off three asynchronous requests, the server or servers do their thing, and send back the data. In this scenario, our data returns in the specified order and we execute each callback as soon as its data is available ready. Even if the others have yet to return.
Let&#x2019;s say we fire off three asynchronous requests, the server or servers do their thing, and send back the data. In this scenario, our data returns in the specified order and we execute each callback as soon as its data is available ready. Even if the others have yet to return.
Let&#x2019;s say we fire off three asynchronous requests, the server or servers do their thing, and send back the data. In this scenario, our data returns in the specified order and we execute each callback as soon as its data is available ready. Even if the others have yet to return.
Let&#x2019;s fire off three asynchronous requests, the server or servers do their thing, and send back the data. We have no control over the timing. In this scenario, our data returns in the specified order and we execute each callback as soon as its data is available ready. Even if the others have yet to return.
Let&#x2019;s say we fire off three asynchronous requests, the server or servers do their thing, and send back the data. In this scenario, our data returns in the specified order and we execute each callback as soon as its data is available ready. Even if the others have yet to return.
Let&#x2019;s say we fire off three asynchronous requests, the server or servers do their thing, and send back the data. In this scenario, our data returns in the specified order and we execute each callback as soon as its data is available ready. Even if the others have yet to return.
Let&#x2019;s say we fire off three asynchronous requests, the server or servers do their thing, and send back the data. In this scenario, our data returns in the specified order and we execute each callback as soon as its data is available ready. Even if the others have yet to return.
Let&#x2019;s say we fire off three asynchronous requests, the server or servers do their thing, and send back the data. In this scenario, our data returns in the specified order and we execute each callback as soon as its data is available ready. Even if the others have yet to return.
Let&#x2019;s say we fire off three asynchronous requests, the server or servers do their thing, and send back the data. In this scenario, our data returns in the specified order and we execute each callback as soon as its data is available ready. Even if the others have yet to return.
In this scenario, our servers will return the data out of order. Note how Callbacks B & C wait for the return of Callback A before firing.
Let&#x2019;s start by looking at some common anti-patterns and see if they look familiar. If they do, you may want to stick around...
The first anti-pattern is serial request/serial response. Successive Ajax requests are nested inside callbacks and executed upon completion of the preceding request. Previous data is accessible to each callback via closure. WALKTHRU...
The second anti-pattern is parallel request / random response. This pattern is quicker because requests are made simultaneously, but usually requires a counter and a common callback which is fired once all requests are complete.
As I mentioned, this pattern is faster, but the code quickly grows bloated, crufty, and significantly harder to maintain.
Sexy.js uses the 3rd Sajax pattern: parallel request/serial response. Requests made in parallel for speed and then by wrapping and eventing callback functions, Sexy ensures proper callback execution order every time.
Originally written as a jQuery plugin, Sexy is now available as a standalone library using jQuery&#x2019;s Ajax. Yay, open source! Both the plugin and standalone pass jQuery as an adapter so I encourage anyone interested in porting Sexy to other libs to do so. I&#x2019;d be happy to help.
Originally written as a jQuery plugin, Sexy is now available as a standalone library using jQuery&#x2019;s Ajax. Yay, open source! Both the plugin and standalone pass jQuery as an adapter so I encourage anyone interested in porting Sexy to other libs to do so. I&#x2019;d be happy to help.
Sexy is a class. New Sexy chains can be constructed by calling new Sexy. And then requests can be made using the returned instance.
Sexy is a class. New Sexy chains can be constructed by calling new Sexy. And then requests can be made using the returned instance.
But I didn&#x2019;t think that was Sexy enough. So I did away with the new keyword.
But I didn&#x2019;t think that was Sexy enough. So I did away with the new keyword.
Let&#x2019;s look inside the Sexy constructor. Sexy checks the instanceof this, which if used with the new keyword would be Sexy. If it&#x2019;s not Sexy, then it was called without the new keyword, so we call it with the new keyword and return the new instance.
Still not sexy enough! A Sexy object can also be instantiated just by calling any one of Sexy&#x2019;s instance methods as a static method of Sexy. (I just thought the extra parentheses were ugly.)
Still not sexy enough! A Sexy object can also be instantiated by calling any one of Sexy&#x2019;s instance methods as a static method of Sexy. (I just thought the extra parentheses were ugly.)
Looking back inside the code, you can see that we just loop the prototypal methods and add static methods that apply the desired method in the scope of a new Sexy instance. Since the API is 100% chainable, returning the method&#x2019;s return value, returns the instance. To which we can chain more calls.
okay, let&#x2019;s take a look at Sexy&#x2019;s api. sexy was designed to be expressive and chainable so that the code looks like what the code does.
okay, let&#x2019;s take a look at Sexy&#x2019;s api. sexy was designed to be expressive and chainable so that the code looks like what the code does.
okay, let&#x2019;s take a look at Sexy&#x2019;s api. sexy was designed to be expressive and chainable so that the code looks like what the code does.
A method for each supported data type. These types reflect the Sexy&#x2019;s jQuery roots with the exception of style, which adds stylesheet support and was added for &#x201C;completeness&#x201D;. Helpful when bootstrapping an app w Sexy. Script and Style have aliases, js and css. This is the shorthand form, and takes a URL and a callback as arguments.
An optional 2nd argument will let you defer the request until the previous request has completed. You will see in a few slides how this allows us to handle server authentication and modify successive requests.
In its verbose form, each method can also take a jQuery-like configuration object, for when you want to POST data or add an error callbacks, etc. Defer is also a configurable property of the configuration object
look up dummy :)
Here we can see two calls being chained. The requests are made simultaneously and the callbacks executed in the specified order. This is an example of the verbose syntax using configuration objects. Note the second argument of the second callback.
This is how Sexy shares data. The return value of a success callback is cached when it is fired and then appended to the arguments of the following success callback when it is ready.
But big configuration objects aren&#x2019;t always sexy. So here&#x2019;s the brief syntax which takes url and callback.
Once again note the sharing of article between callbacks. But notice how we&#x2019;re just returning article. THis seems like something we&#x2019;ll do quite frequently, so...
Sexy provides implicit callbacks. If you do not specify a callback, a pass thru function will be used to pass your results immediately to the next callback.
Note article just automagically appears as an argument to our second callback.
Since scripts and styles don&#x2019;t usually bring back data we want to interpret, if there is no callback, we pass thru the return value of the previous callback.
You can stack as many as you want in there and the article will still get through. (of course that decreases the readability and should be avoided)
Using defer we can force subsequent calls to behave in a serial request/serial response pattern, but we still benefit from the enhanced data availablility. Once logged in, we get the article, we can then manipulate it and pass it to the next request as its data property for posting before logging out.
Sexy (like jQuery) loads local scripts as text and inserts them into the DOM, so managing script dependencies is as easy as writing a grocery list, a Secy grocery list.
now its time for a Sexy Sajax makeover...
Remember our parallel request / random response anti-pattern? Let&#x2019;s add a little sexy...
and voila! all rise for your royal hotness.
Here you can see that we want to display a loading indicator while the article loads, but its not so important while the comments load, so by passing any falsy value you can unset the previous config
you can save yourself some keystrokes by passing your initial setup to the constructor
Sexy also provides a sort of client-side Javascript packaging tool called Sexy.bundle...
Bundle makes multiple requests and a single DOM insertion and then executes an optional callback. Because of the way sexy is designed, the script sequence and therefore your dependencies are preserved.
Bundle makes multiple requests and a single DOM insertion and then executes an optional callback. Because of the way sexy is designed, the script sequence and therefore your dependencies are preserved.
Bundle makes multiple requests and a single DOM insertion and then executes an optional callback. Because of the way sexy is designed, the script sequence and therefore your dependencies are preserved.
Bundle makes multiple requests and a single DOM insertion and then executes an optional callback. Because of the way sexy is designed, the script sequence and therefore your dependencies are preserved.
Bundle makes multiple requests and a single DOM insertion and then executes an optional callback. Because of the way sexy is designed, the script sequence and therefore your dependencies are preserved.
Bundle makes multiple requests and a single DOM insertion and then executes an optional callback. Because of the way sexy is designed, the script sequence and therefore your dependencies are preserved.
Bundle makes multiple requests and a single DOM insertion and then executes an optional callback. Because of the way sexy is designed, the script sequence and therefore your dependencies are preserved.