Hacker Newsnew | past | comments | ask | show | jobs | submitlogin
Multiple Simultaneous Ajax Requests (with one callback) in jQuery (css-tricks.com)
73 points by uptown on Feb 14, 2014 | hide | past | favorite | 30 comments


globalStore? Ewwwww. As the jQuery documentation states on $.when [1], the .then() callback function will be called with a number of arguments equal to those passed to $.when(), ergo in this example:

.then(function(html, css, feature) {});

Which avoids the need for a global / shared object. If you need access to these resources outside of this one callback, prefer to pass the promise object itself around; promises allow multiple 'then's to be added, either before or after the promise resolves.

I'm working on a blog post about promises and related patterns (in the context / implementation of Angular, but they're equally valid for jQuery or other promise implementations), I'll post it on HN hopefully somewhere this weekend or early next week.

[1] https://api.jquery.com/jQuery.when/


Thank you for clarifying this!



   $.when(
     // Get the css-tricks once
     $.get("http://css-tricks.com"),

     // get it twice
     $.get("http://css-tricks.com")
    ).then(function( csstricks1, csstricks2 ) {
      
      console.log( 'Fetched css tricks' );
  
      console.log( csstricks1, csstricks2 );
    });
csstricks1[0] is the content object and usually what you'll want - for example, if the response is json.


Why would you fetch the same thing twice? Or is that just for you example and wouldn't be done in reality?


Just to be sure that one of them isn't corrupted.


Can't get enough of deferreds and promises? Want lots more examples of interesting, cunning and mind bending ways to use promises and deferreds? As luck would have it, this:

http://shop.oreilly.com/product/0636920030508.do

...has just been published.

(N.B. I'm one of the authors - all feedback would be most welcome and apologies for the shameless plug).


I don't mean to shit on your book, but an entire book dedicated to jQuery deferreds? There is that much to say about them?


It's more a matter of learning how you can use them in various ways, and also of really getting into the habit of thinking with deferreds. I've been using them for about 7 years (mainly in Python) and I'm still finding interesting new ways to think about them, new tricks, etc. [Disclaimer: I'm also one of the book's authors.] BTW, if you use AUTHD as a discount code on the O'Reilly site, you'll get 50% off the e-book price or 40% off a dead tree version.


Buy it and you'll find out... ;-)

I wrote this high-level piece of fluff as a taster for the Guardian's developer blog:

http://www.theguardian.com/info/developer-blog/2013/sep/17/d...

"If Doctor Who were a programmer, he'd use deferreds!"


Loving the book, seriously the examples are easy to follow and realy well paced.


Great :-)


Thanks!


Nice introduction to the promise concept. It's very interesting take a look to the oficial documentation https://api.jquery.com/category/deferred-object/ for more advanced features.


And remember to use fun.prototype.apply if you're argument to $.fn.when is an array of deferreds or a function call that returns said array. E.g. $.when.apply(thisArg, array_of_deferreds).


Please let me know if this is a horrible UI pattern (and I'd love to hear alternatives), but this could also be used to implement something like "do X, after Y succeeds and at least Z milliseconds have passed".

For example, if you have a Search button that makes an AJAX request, and there's a loading spinner while waiting for that request, you could use this technique to make the spinner show for at least, say 500 milliseconds. I have noticed that a lot of AJAX search forms return so quickly that the loading spinner just barely flickers before the results display. It might be less jarring if you ensured that the spinner would show for at least 500 ms. Of course, you don't just want to add a 500 ms delay after the request returns, because then slow requests will get that much slower.


Or you can make a count-down latch of some kind:

  var num_results = 3;
  var results = []
  var makeCallback = function(index) {
    return function(response) {
      num_results -= 1;
      results[index] = response;
      if (num_results > 0) {
        return;
      }
      
      // actually do stuff here, all results are loaded.
    };
  };
  $.get("/a", makeCallback(0));
  $.get("/b", makeCallback(1));
  $.get("/c", makeCallback(2));
  // etc
It's also not hard to make a generic latch-producing function so you can just write stuff like:

  var l = makeLatch(callback);
  $.get("/a", l());
  $.get("/b", l());
  $.get("/c", l());


True, and this would work, but why would you favor this over Promises? They're an open, well-known spec with a lot of implementations - hell, some browsers support them natively. Promises also offer better control over sequential action and error handling.


Yes, you can reinvent wheels and avoid javascript best practices, and lose all benefits of async code control.


Latches aren't async code control? Javascript has (async) best practices that survive more than a couple years?

Promises are great, I totally agree (as long as they're A+ compliant). But they're not on every platform, and it's not (usually) worth building your own if it's not there.


A 'count-down latch' is commonly (at least when I learned it, using pthreads) called a 'Conditional Variable'.

In your case case, your mutex would be the num_results variable and the conditional is that it is greater than 0.


Like many, I had written myself a similar utility some years ago because "I need several stuffs that don't depend on each other, so they could be downloaded or calculated at the same time to get the end result faster" is a pattern that often comes up.

Nowadays I use "async.js" (https://github.com/caolan/async): does the same, but with extra features.

It doesn't rely on jQuery unlike the snipplets of the article, so it's useful when you're aiming for vanilla or want to share code with Node.

It's far from the only library of this type, but I like it because it's reliable and has a good balance of simple yet tweakable for uncommon workflows.


I also like promises-style solutions, but in practice it felt like it needed more things modified to work with them than async when mixing with third-party libraries required by projects, but that's more a gut feeling than backed by hard numbers, so I'll reevaluate that assertion when the right project comes along.


As as extension to this idea, I do stuff like this sometimes in coffee.

$.when.apply($, (object.request() for object in objects)).done (responses...) -> doStuff()


Why he says about one callback when he really has four? Not even saying about globalStore.


This is pretty similar to using RequireJS no?


Promises are the way you should be doing AJAX, really.


And that is how $.when and $.then works, no?


...which is why I upvoted the post? Just saying, a lot of people aren't aware jQ even has them, even if it's not inline with the A+ spec.


Yes, promises are great. It would be nice to have a function on a promise that returns a regular callback which you can pass to functions that only know about callbacks.

Also, if you are using promises for getter functions, you'll have to store those promises somewhere, so that next time you don't load them again. Basically "getting" a resource involves caching, promises, and maybe even throttling. So its ideal implementation is not really just a promise.

Check this out: http://platform.qbix.com/guide/patterns




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: