0

A JS control calls a data service and continues rendering itself without waiting for the result. Sometimes the service returns after the the controls is being fully rendered, sometimes - before. How do you implement WaitForAll in JS? I'm using jQuery.

Here's what I've done myself: (Utils.WaitForAll simply counts the number of hits once it's matched with the count it calls handle)

// before we started
var waiter = Utils.WaitFor({handle: function(e){ alert("got called"; }, count: 2});

the way it gets triggered:

// place one
waiter.Notify({one: {...}});

and then

// place two (can occur before one though)
waiter.Notify({two: {...}});

which triggers handle, handle has values tagged as one & two in its e. Waiter is an extra 'global' var, travelling down the stack, which i didn't quite like and it's a another new object after all... Any obvious problems with my approach?

user1514042
  • 1,899
  • 7
  • 31
  • 57
  • Most likely the data service has a callback of sorts that tells you when it is done. you'll need to use it. – Kevin B May 13 '13 at 14:46
  • It does indeed, I'm just looking for a synchronization pattern example... – user1514042 May 13 '13 at 14:50
  • You can't do that without making data service synchronous, which is probably a [bad idea](http://stackoverflow.com/questions/6517403/what-are-the-drawbacks-of-using-synchronous-ajax-call). – Kevin B May 13 '13 at 14:51
  • It is indeed, just need something which will accept to inbound calls an only proceed when both calls have arrived... I did it myself in a rather messy way was looking a professional take on it. – user1514042 May 13 '13 at 14:53
  • well, there's fancy ways of adding callbacks such as using deferred objects, but since we don't know what you're working with, we can't really suggest anything. In almost every case it's just callback usage if it is to work asynchronously. – Kevin B May 13 '13 at 14:54
  • Can't you just use the jQuery function $.done (can be nested), or am I missing something? – Chris Dixon May 13 '13 at 15:17
  • @Chris Dixon Could you post up a quick sample? I've just looked at it and couldn't figure out how it can manage 2 or 2 concurrent threads. – user1514042 May 13 '13 at 15:23
  • @user1514042 there is no "concurrent threads" in javascript. there is only one thread at a time for a given page – Avinash R May 13 '13 at 15:42

2 Answers2

3

You should take a look a promise interface of CommonJS (implemented by jQuery.Deferred) it provides progress callback which can be used in this case.

sample code:

var waiter = $.Deferred();
var len = 2;
waiter.done(function() {
   alert("Hooray!!!");
});
waiter.progress(function() {
    if(--len === 0) {
        waiter.resolve();
    }
});
// somewhere
$.ajax({
    ...
    data: somedata,
    success: function() {
        waiter.notify();
    }
});
// somewhere else
$.ajax({
    ...
    data: someotherdata,
    success: function() {
        waiter.notify();
    }
});

More about deferred:

Community
  • 1
  • 1
Avinash R
  • 3,101
  • 1
  • 27
  • 47
  • This is the right path. To elaborate, `Deferred.when` can be used to wait for multiple promise objects to resolve (i.e., for multiple parallel things to finish). You can use the `Deferred` constructor to make a promise object out of any code so that it "resolves" when its callback is called. – harpo May 13 '13 at 15:30
  • Could you explain how len gets updated - it isn't exactly clear from the code. – user1514042 May 14 '13 at 12:38
  • @user1514042 sorry, I didn't add any logic for decrementing `len` previously. I've updated my answer. hope it's clear now to you. – Avinash R May 14 '13 at 13:27
  • the `len` is not important here, what you have to understand is that waiting for the service(s) to complete before rendering is a bad idea as the whole thread will be blocked. Which is not desired here. Instead the rendering should be done *asyncronously* to start with. This is a common design change you have to embrace if you come from programming Multi-threaded environment. Also, as there is in Python, there is no `yield` keyword in JavaScript; which will do the same kind of functionality without this much ado. – Avinash R May 14 '13 at 13:36
  • well, you can rely on something which doesn't exist, it completely invalidates the logic. let's park it. – user1514042 May 14 '13 at 14:28
  • well as @KevinB suggested earlier, the _method_ you asked for itself is flawed, so I gave an alternative method; your _logic_ is not being invalidated here. I suggest you read about the method in the referring materials a bit more deeper. – Avinash R May 15 '13 at 03:00
0

I've found exactly wheat I need being jQuery Deferred, see the article: http://richardneililagan.com/2011/05/using-deferred-objects-in-jquery-1-5/

user1514042
  • 1,899
  • 7
  • 31
  • 57