librelist archives

« back to archive

Callbacks and patterns question

Callbacks and patterns question

From:
Marcin Szczepanski
Date:
2012-07-08 @ 02:06
I don't really know how to search for what I'm trying to ask, so I'll throw
it out to the list for advice.

The project I am working on involves a lot of async calls (both to external
services and WebSQL - it's a mobile app wrapped with PhoneGap).

I quite often have something like this:
- if not logged in then login
- get something from the remote server

The issue is that the login is async and so is the get something, currently
I end up with code like this (contrived example):

var _getSomething = function ()
{
   anAsyncCall( function(result) {
     doSomethingWith(result);
   });
}

if (!loggedIn)
{
   login( function () {
     _getSomething();
   }
}
else
{
   _getSomething();
}

... I'm putting the "getSomething" into a closure to not repeat the same
code (in reality there's usually a few more lines that happen as a result
of the async call).

It works, but in the interests of efficiency is there a better pattern for
doing this? It just seems a bit clunky and you end up with a bunch of if /
elses that can be hard to follow..

Look forward to seeing what you all think!

- Marcin

-- 
M.

Re: [sydjs] Callbacks and patterns question

From:
Joseph Gentle
Date:
2012-07-08 @ 02:35
On Sun, Jul 8, 2012 at 12:06 PM, Marcin Szczepanski <marcins@gmail.com> wrote:
> I don't really know how to search for what I'm trying to ask, so I'll throw
> it out to the list for advice.
>
> The project I am working on involves a lot of async calls (both to external
> services and WebSQL - it's a mobile app wrapped with PhoneGap).
>
> I quite often have something like this:
> - if not logged in then login
> - get something from the remote server
>
> The issue is that the login is async and so is the get something, currently
> I end up with code like this (contrived example):
>
> var _getSomething = function ()
> {
>    anAsyncCall( function(result) {
>      doSomethingWith(result);
>    });
> }

Start getting used to passing callbacks to heaps of your functions.
The standard I use (from nodejs) is to make all callback functions
take any errors as the first argument, and results following that. Eg:

var _getSomething = function (callback)
{
   anAsyncCall( function(result) {
     if(result.error) {
       callback(result.error);
     } else {
       callback(null, result);
     }
   });
}

> if (!loggedIn)
> {
>    login( function () {
>      _getSomething();
>    }
> }
> else
> {
>    _getSomething();
> }

Write a function like this:

var whenLoggedIn(callback) {
  if(!loggedIn) {
    login(callback);
  } else {
    callback();
  }
}

... Then you can call whenLoggedIn(function() {...}) with impunity.
You probably also want to make whenLoggedIn pass login errors to the
callback if you've given up trying to login. Also, whenLoggedIn should
call login() exactly once. Currently if it gets called while you're
logging in it'll call login() again. I'll leave those changes up to
you.

Hope that helps.
-J

>
> ... I'm putting the "getSomething" into a closure to not repeat the same
> code (in reality there's usually a few more lines that happen as a result of
> the async call).
>
> It works, but in the interests of efficiency is there a better pattern for
> doing this? It just seems a bit clunky and you end up with a bunch of if /
> elses that can be hard to follow..
>
> Look forward to seeing what you all think!
>
> - Marcin
>
> --
> M.

Re: [sydjs] Callbacks and patterns question

From:
Dominic Tarr
Date:
2012-07-08 @ 02:56
I bet you have a bunch of different calls in which you need to log in first.
you can use higher order function to make this really tidy

function loginIf(funx) {
  return function () {
    var args = [].slice.call(arguments)
    var callback = args[args.length - 1] //last arg is callback.
    if(loggedin)
      return funx.apply(null, args)
    login(function (err) {
       if(err) return callback(err) //could not callfunx because auth failed...
       return funx.apply(null, args)
    })
  }
}

loginIf returns a function that wraps funx that will login if
necessary, then call funx.

now, whenever you have a async call that must be logged in first, do this

loginIf(doSomething)(argsForDoSomething,..., function (err) {
  //TOO EASY
})

also, notice there is less nesting!

On Sun, Jul 8, 2012 at 2:35 PM, Joseph Gentle <josephg@gmail.com> wrote:
> On Sun, Jul 8, 2012 at 12:06 PM, Marcin Szczepanski <marcins@gmail.com> wrote:
>> I don't really know how to search for what I'm trying to ask, so I'll throw
>> it out to the list for advice.
>>
>> The project I am working on involves a lot of async calls (both to external
>> services and WebSQL - it's a mobile app wrapped with PhoneGap).
>>
>> I quite often have something like this:
>> - if not logged in then login
>> - get something from the remote server
>>
>> The issue is that the login is async and so is the get something, currently
>> I end up with code like this (contrived example):
>>
>> var _getSomething = function ()
>> {
>>    anAsyncCall( function(result) {
>>      doSomethingWith(result);
>>    });
>> }
>
> Start getting used to passing callbacks to heaps of your functions.
> The standard I use (from nodejs) is to make all callback functions
> take any errors as the first argument, and results following that. Eg:
>
> var _getSomething = function (callback)
> {
>    anAsyncCall( function(result) {
>      if(result.error) {
>        callback(result.error);
>      } else {
>        callback(null, result);
>      }
>    });
> }
>
>> if (!loggedIn)
>> {
>>    login( function () {
>>      _getSomething();
>>    }
>> }
>> else
>> {
>>    _getSomething();
>> }
>
> Write a function like this:
>
> var whenLoggedIn(callback) {
>   if(!loggedIn) {
>     login(callback);
>   } else {
>     callback();
>   }
> }
>
> ... Then you can call whenLoggedIn(function() {...}) with impunity.
> You probably also want to make whenLoggedIn pass login errors to the
> callback if you've given up trying to login. Also, whenLoggedIn should
> call login() exactly once. Currently if it gets called while you're
> logging in it'll call login() again. I'll leave those changes up to
> you.
>
> Hope that helps.
> -J
>
>>
>> ... I'm putting the "getSomething" into a closure to not repeat the same
>> code (in reality there's usually a few more lines that happen as a result of
>> the async call).
>>
>> It works, but in the interests of efficiency is there a better pattern for
>> doing this? It just seems a bit clunky and you end up with a bunch of if /
>> elses that can be hard to follow..
>>
>> Look forward to seeing what you all think!
>>
>> - Marcin
>>
>> --
>> M.

Re: [sydjs] Callbacks and patterns question

From:
Jonathon Creenaune
Date:
2012-07-08 @ 09:50
An alternative to passing callbacks around is to use promises. I'd go with
Joseph's approach of wrapping the login check in a function, but write it
like:

function whenLoggedIn() {
    var deferred = jQuery.Deferred();
    if (!loggedIn) {
        // If you have control over the login function, you could make that
return a promise too.
        // Otherwise map success/error handlers to the deferred's
resolve/reject
        login(function() {
            deferred.resolve(); // success
        }, function() {
            deferred.reject(); // failure
        });
    }
    return deferred.promise();
}

whenLoggedIn().done(function() {
    // anAsyncCall returns a promise too
    anAsyncCall(arg1, arg2).done(function(result) {
        doSomethingWith(result);
   });
});

More info at http://api.jquery.com/category/deferred-object/, but there are
a bunch of deferred / promise libraries for browser and server.

I like it because it's there's a clear distinction between what you're
passing to be consumed by the function (eg arg1, arg2 to anAsyncCall) and
what occurs in response to that function executing. Passing success & error
callbacks as arguments to a function (especially one that accepts multiple
parameters) can get a bit murky. It also lets jQuery handle the plumbing of
"if success callback exists then invoke success with these args ..."

Re: [sydjs] Callbacks and patterns question

From:
Sugendran Ganess
Date:
2012-07-08 @ 02:31
I like to do something like this:
// -- START CODE --
function getSomething(callback) {
	if(loggedIn) {
		// if we are logged in, then we have someThing
		// and should return early to the callback
		return callback(someThing);
	}
	login(function(){
		// gotta get something from somewhere
		someThing = _getSomething();
		callback(someThing);
	});
}

// usage:
getSomething(doSomething);

// where doSomething is a function that has a param
// requiring something
// -- END CODE --

The other way to look at is to have the login function
determine if you're logged in or not and log you in
appropriately, so something like this:

// -- START CODE --
var loggedIn = false;
function login(callback) {
	if(loggedIn) {
		return callback();
	}
	asyncLogin(function(){
		loggedIn = true;
		callback();
	});
}

// usage:
login(function(){
	getSomething();
});

// -- END CODE --

I tend to prefer the first option because I don't like the parts using
my 'library layer' having to worry about things like are we logged in
or is the sky blue - I just want them to come back with an appropriate
result.

Hope that isn't too confusing...

-- Sugendran

On 8 July 2012 12:06, Marcin Szczepanski <marcins@gmail.com> wrote:
> I don't really know how to search for what I'm trying to ask, so I'll throw
> it out to the list for advice.
>
> The project I am working on involves a lot of async calls (both to external
> services and WebSQL - it's a mobile app wrapped with PhoneGap).
>
> I quite often have something like this:
> - if not logged in then login
> - get something from the remote server
>
> The issue is that the login is async and so is the get something, currently
> I end up with code like this (contrived example):
>
> var _getSomething = function ()
> {
>    anAsyncCall( function(result) {
>      doSomethingWith(result);
>    });
> }
>
> if (!loggedIn)
> {
>    login( function () {
>      _getSomething();
>    }
> }
> else
> {
>    _getSomething();
> }
>
> ... I'm putting the "getSomething" into a closure to not repeat the same
> code (in reality there's usually a few more lines that happen as a result of
> the async call).
>
> It works, but in the interests of efficiency is there a better pattern for
> doing this? It just seems a bit clunky and you end up with a bunch of if /
> elses that can be hard to follow..
>
> Look forward to seeing what you all think!
>
> - Marcin
>
> --
> M.

Re: [sydjs] Callbacks and patterns question

From:
Benjamin Lupton
Date:
2012-07-08 @ 18:12
For all the Bevry projects - https://github.com/bevry - we use the flow
control library in bal-util - https://github.com/balupton/bal-util - which
runs in the browser and in node.

Here's some example usage for it:
https://github.com/balupton/bal-util/blob/master/src/test/flow.test.coffee#L89-184

Basically you define a group of tasks, and a completion callback for when
those tasks complete. You then add your tasks (be them async or sync) to
the group. Once all the tasks are added you then run your tasks in all at
once using myTasksGroup.async() or one after the other using
myTasksGroup.sync() - if any errors occur the group wills top executing
more tasks, and fire the completion callback with the error as the first
argument.

It's really simplified a lot of the complicated async and sync combinations
we use in all our work, and it powers the new Joe (also runs in the browser
and node) testing framework: https://github.com/bevry/joe/wiki/Using

Keen to hear everyone's thoughts :)
- Benjamin


On 8 July 2012 12:06, Marcin Szczepanski <marcins@gmail.com> wrote:

> I don't really know how to search for what I'm trying to ask, so I'll
> throw it out to the list for advice.
>
> The project I am working on involves a lot of async calls (both to
> external services and WebSQL - it's a mobile app wrapped with PhoneGap).
>
> I quite often have something like this:
> - if not logged in then login
> - get something from the remote server
>
> The issue is that the login is async and so is the get something,
> currently I end up with code like this (contrived example):
>
> var _getSomething = function ()
> {
>    anAsyncCall( function(result) {
>      doSomethingWith(result);
>    });
> }
>
> if (!loggedIn)
> {
>    login( function () {
>      _getSomething();
>    }
> }
> else
> {
>    _getSomething();
> }
>
> ... I'm putting the "getSomething" into a closure to not repeat the same
> code (in reality there's usually a few more lines that happen as a result
> of the async call).
>
> It works, but in the interests of efficiency is there a better pattern for
> doing this? It just seems a bit clunky and you end up with a bunch of if /
> elses that can be hard to follow..
>
> Look forward to seeing what you all think!
>
> - Marcin
>
> --
> M.
>

Re: [sydjs] Callbacks and patterns question

From:
Joseph Gentle
Date:
2012-07-09 @ 02:01
Thats quite a nice little library. If you want those tests to run
faster, I wrote a little library that stubs out setTimeout,
setInterval, Date.now(), etc with fake versions. The fake versions let
you fast forward through time, so you can remove any actual delays in
your tests. There should be no difference programatically (Your
timeouts still happen in order, and Date.now() still reports time
passing) but your unit tests run super fast.

https://github.com/josephg/node-timerstub

Porting it to run it in the browser would be trivial - the whole
library is 76 lines and it has no dependancies except for
process.nextTick.

-J


On Mon, Jul 9, 2012 at 4:12 AM, Benjamin Lupton <b@lupton.cc> wrote:
> For all the Bevry projects - https://github.com/bevry - we use the flow
> control library in bal-util - https://github.com/balupton/bal-util - which
> runs in the browser and in node.
>
> Here's some example usage for it:
> 
https://github.com/balupton/bal-util/blob/master/src/test/flow.test.coffee#L89-184
>
> Basically you define a group of tasks, and a completion callback for when
> those tasks complete. You then add your tasks (be them async or sync) to the
> group. Once all the tasks are added you then run your tasks in all at once
> using myTasksGroup.async() or one after the other using myTasksGroup.sync()
> - if any errors occur the group wills top executing more tasks, and fire the
> completion callback with the error as the first argument.
>
> It's really simplified a lot of the complicated async and sync combinations
> we use in all our work, and it powers the new Joe (also runs in the browser
> and node) testing framework: https://github.com/bevry/joe/wiki/Using
>
> Keen to hear everyone's thoughts :)
> - Benjamin
>
>
> On 8 July 2012 12:06, Marcin Szczepanski <marcins@gmail.com> wrote:
>>
>> I don't really know how to search for what I'm trying to ask, so I'll
>> throw it out to the list for advice.
>>
>> The project I am working on involves a lot of async calls (both to
>> external services and WebSQL - it's a mobile app wrapped with PhoneGap).
>>
>> I quite often have something like this:
>> - if not logged in then login
>> - get something from the remote server
>>
>> The issue is that the login is async and so is the get something,
>> currently I end up with code like this (contrived example):
>>
>> var _getSomething = function ()
>> {
>>    anAsyncCall( function(result) {
>>      doSomethingWith(result);
>>    });
>> }
>>
>> if (!loggedIn)
>> {
>>    login( function () {
>>      _getSomething();
>>    }
>> }
>> else
>> {
>>    _getSomething();
>> }
>>
>> ... I'm putting the "getSomething" into a closure to not repeat the same
>> code (in reality there's usually a few more lines that happen as a result of
>> the async call).
>>
>> It works, but in the interests of efficiency is there a better pattern for
>> doing this? It just seems a bit clunky and you end up with a bunch of if /
>> elses that can be hard to follow..
>>
>> Look forward to seeing what you all think!
>>
>> - Marcin
>>
>> --
>> M.
>
>

Re: [sydjs] Callbacks and patterns question

From:
Joshua Street
Date:
2012-07-09 @ 02:13
Hi Joseph,

I'm not very familiar with writing JS tests (mostly on this list to listen
and learn!) but how do you avoid race conditions in this 'compressed time'
test scenario where functions are called  outside of setTimeout and co.? Or
is the whole point that this uncovers these things so they can be made more
robust?

Cheers,
Josh

On Mon, Jul 9, 2012 at 12:01 PM, Joseph Gentle <josephg@gmail.com> wrote:

> Thats quite a nice little library. If you want those tests to run
> faster, I wrote a little library that stubs out setTimeout,
> setInterval, Date.now(), etc with fake versions. The fake versions let
> you fast forward through time, so you can remove any actual delays in
> your tests. There should be no difference programatically (Your
> timeouts still happen in order, and Date.now() still reports time
> passing) but your unit tests run super fast.
>
> https://github.com/josephg/node-timerstub
>
> Porting it to run it in the browser would be trivial - the whole
> library is 76 lines and it has no dependancies except for
> process.nextTick.
>
> -J
>
>
> On Mon, Jul 9, 2012 at 4:12 AM, Benjamin Lupton <b@lupton.cc> wrote:
> > For all the Bevry projects - https://github.com/bevry - we use the flow
> > control library in bal-util - https://github.com/balupton/bal-util -
> which
> > runs in the browser and in node.
> >
> > Here's some example usage for it:
> >
> 
https://github.com/balupton/bal-util/blob/master/src/test/flow.test.coffee#L89-184
> >
> > Basically you define a group of tasks, and a completion callback for when
> > those tasks complete. You then add your tasks (be them async or sync) to
> the
> > group. Once all the tasks are added you then run your tasks in all at
> once
> > using myTasksGroup.async() or one after the other using
> myTasksGroup.sync()
> > - if any errors occur the group wills top executing more tasks, and fire
> the
> > completion callback with the error as the first argument.
> >
> > It's really simplified a lot of the complicated async and sync
> combinations
> > we use in all our work, and it powers the new Joe (also runs in the
> browser
> > and node) testing framework: https://github.com/bevry/joe/wiki/Using
> >
> > Keen to hear everyone's thoughts :)
> > - Benjamin
> >
> >
> > On 8 July 2012 12:06, Marcin Szczepanski <marcins@gmail.com> wrote:
> >>
> >> I don't really know how to search for what I'm trying to ask, so I'll
> >> throw it out to the list for advice.
> >>
> >> The project I am working on involves a lot of async calls (both to
> >> external services and WebSQL - it's a mobile app wrapped with PhoneGap).
> >>
> >> I quite often have something like this:
> >> - if not logged in then login
> >> - get something from the remote server
> >>
> >> The issue is that the login is async and so is the get something,
> >> currently I end up with code like this (contrived example):
> >>
> >> var _getSomething = function ()
> >> {
> >>    anAsyncCall( function(result) {
> >>      doSomethingWith(result);
> >>    });
> >> }
> >>
> >> if (!loggedIn)
> >> {
> >>    login( function () {
> >>      _getSomething();
> >>    }
> >> }
> >> else
> >> {
> >>    _getSomething();
> >> }
> >>
> >> ... I'm putting the "getSomething" into a closure to not repeat the same
> >> code (in reality there's usually a few more lines that happen as a
> result of
> >> the async call).
> >>
> >> It works, but in the interests of efficiency is there a better pattern
> for
> >> doing this? It just seems a bit clunky and you end up with a bunch of
> if /
> >> elses that can be hard to follow..
> >>
> >> Look forward to seeing what you all think!
> >>
> >> - Marcin
> >>
> >> --
> >> M.
> >
> >
>



-- 
Josh Street

http://josh.st/
+61 (0) 425 808 469

Re: [sydjs] Callbacks and patterns question

From:
Dominic Tarr
Date:
2012-07-09 @ 02:21
I understand that setTimeout is actually not strictly ordered.
two setTimeouts with the same time will be ordered
but setTimeout(F, 10) may occur after setTimeout(F, 11)

this is setTimeout creates a timer in a new thread,
and whether they regain control at the right time depends on the schedular.

I have not experienced this first hand, but I remember reading this in
the nodejs mailing list.


On Mon, Jul 9, 2012 at 2:13 PM, Joshua Street <josh.street@gmail.com> wrote:
> Hi Joseph,
>
> I'm not very familiar with writing JS tests (mostly on this list to listen
> and learn!) but how do you avoid race conditions in this 'compressed time'
> test scenario where functions are called  outside of setTimeout and co.? Or
> is the whole point that this uncovers these things so they can be made more
> robust?
>
> Cheers,
> Josh
>
>
> On Mon, Jul 9, 2012 at 12:01 PM, Joseph Gentle <josephg@gmail.com> wrote:
>>
>> Thats quite a nice little library. If you want those tests to run
>> faster, I wrote a little library that stubs out setTimeout,
>> setInterval, Date.now(), etc with fake versions. The fake versions let
>> you fast forward through time, so you can remove any actual delays in
>> your tests. There should be no difference programatically (Your
>> timeouts still happen in order, and Date.now() still reports time
>> passing) but your unit tests run super fast.
>>
>> https://github.com/josephg/node-timerstub
>>
>> Porting it to run it in the browser would be trivial - the whole
>> library is 76 lines and it has no dependancies except for
>> process.nextTick.
>>
>> -J
>>
>>
>> On Mon, Jul 9, 2012 at 4:12 AM, Benjamin Lupton <b@lupton.cc> wrote:
>> > For all the Bevry projects - https://github.com/bevry - we use the flow
>> > control library in bal-util - https://github.com/balupton/bal-util -
>> > which
>> > runs in the browser and in node.
>> >
>> > Here's some example usage for it:
>> >
>> > 
https://github.com/balupton/bal-util/blob/master/src/test/flow.test.coffee#L89-184
>> >
>> > Basically you define a group of tasks, and a completion callback for
>> > when
>> > those tasks complete. You then add your tasks (be them async or sync) to
>> > the
>> > group. Once all the tasks are added you then run your tasks in all at
>> > once
>> > using myTasksGroup.async() or one after the other using
>> > myTasksGroup.sync()
>> > - if any errors occur the group wills top executing more tasks, and fire
>> > the
>> > completion callback with the error as the first argument.
>> >
>> > It's really simplified a lot of the complicated async and sync
>> > combinations
>> > we use in all our work, and it powers the new Joe (also runs in the
>> > browser
>> > and node) testing framework: https://github.com/bevry/joe/wiki/Using
>> >
>> > Keen to hear everyone's thoughts :)
>> > - Benjamin
>> >
>> >
>> > On 8 July 2012 12:06, Marcin Szczepanski <marcins@gmail.com> wrote:
>> >>
>> >> I don't really know how to search for what I'm trying to ask, so I'll
>> >> throw it out to the list for advice.
>> >>
>> >> The project I am working on involves a lot of async calls (both to
>> >> external services and WebSQL - it's a mobile app wrapped with
>> >> PhoneGap).
>> >>
>> >> I quite often have something like this:
>> >> - if not logged in then login
>> >> - get something from the remote server
>> >>
>> >> The issue is that the login is async and so is the get something,
>> >> currently I end up with code like this (contrived example):
>> >>
>> >> var _getSomething = function ()
>> >> {
>> >>    anAsyncCall( function(result) {
>> >>      doSomethingWith(result);
>> >>    });
>> >> }
>> >>
>> >> if (!loggedIn)
>> >> {
>> >>    login( function () {
>> >>      _getSomething();
>> >>    }
>> >> }
>> >> else
>> >> {
>> >>    _getSomething();
>> >> }
>> >>
>> >> ... I'm putting the "getSomething" into a closure to not repeat the
>> >> same
>> >> code (in reality there's usually a few more lines that happen as a
>> >> result of
>> >> the async call).
>> >>
>> >> It works, but in the interests of efficiency is there a better pattern
>> >> for
>> >> doing this? It just seems a bit clunky and you end up with a bunch of
>> >> if /
>> >> elses that can be hard to follow..
>> >>
>> >> Look forward to seeing what you all think!
>> >>
>> >> - Marcin
>> >>
>> >> --
>> >> M.
>> >
>> >
>
>
>
>
> --
> Josh Street
>
> http://josh.st/
> +61 (0) 425 808 469

Re: [sydjs] Callbacks and patterns question

From:
Joseph Gentle
Date:
2012-07-09 @ 02:45
Javascript is always run in a single thread. A setTimeout can't fire
while your function is executing. So there's no race.

-J

On Mon, Jul 9, 2012 at 12:13 PM, Joshua Street <josh.street@gmail.com> wrote:
> Hi Joseph,
>
> I'm not very familiar with writing JS tests (mostly on this list to listen
> and learn!) but how do you avoid race conditions in this 'compressed time'
> test scenario where functions are called  outside of setTimeout and co.? Or
> is the whole point that this uncovers these things so they can be made more
> robust?
>
> Cheers,
> Josh
>
>
> On Mon, Jul 9, 2012 at 12:01 PM, Joseph Gentle <josephg@gmail.com> wrote:
>>
>> Thats quite a nice little library. If you want those tests to run
>> faster, I wrote a little library that stubs out setTimeout,
>> setInterval, Date.now(), etc with fake versions. The fake versions let
>> you fast forward through time, so you can remove any actual delays in
>> your tests. There should be no difference programatically (Your
>> timeouts still happen in order, and Date.now() still reports time
>> passing) but your unit tests run super fast.
>>
>> https://github.com/josephg/node-timerstub
>>
>> Porting it to run it in the browser would be trivial - the whole
>> library is 76 lines and it has no dependancies except for
>> process.nextTick.
>>
>> -J
>>
>>
>> On Mon, Jul 9, 2012 at 4:12 AM, Benjamin Lupton <b@lupton.cc> wrote:
>> > For all the Bevry projects - https://github.com/bevry - we use the flow
>> > control library in bal-util - https://github.com/balupton/bal-util -
>> > which
>> > runs in the browser and in node.
>> >
>> > Here's some example usage for it:
>> >
>> > 
https://github.com/balupton/bal-util/blob/master/src/test/flow.test.coffee#L89-184
>> >
>> > Basically you define a group of tasks, and a completion callback for
>> > when
>> > those tasks complete. You then add your tasks (be them async or sync) to
>> > the
>> > group. Once all the tasks are added you then run your tasks in all at
>> > once
>> > using myTasksGroup.async() or one after the other using
>> > myTasksGroup.sync()
>> > - if any errors occur the group wills top executing more tasks, and fire
>> > the
>> > completion callback with the error as the first argument.
>> >
>> > It's really simplified a lot of the complicated async and sync
>> > combinations
>> > we use in all our work, and it powers the new Joe (also runs in the
>> > browser
>> > and node) testing framework: https://github.com/bevry/joe/wiki/Using
>> >
>> > Keen to hear everyone's thoughts :)
>> > - Benjamin
>> >
>> >
>> > On 8 July 2012 12:06, Marcin Szczepanski <marcins@gmail.com> wrote:
>> >>
>> >> I don't really know how to search for what I'm trying to ask, so I'll
>> >> throw it out to the list for advice.
>> >>
>> >> The project I am working on involves a lot of async calls (both to
>> >> external services and WebSQL - it's a mobile app wrapped with
>> >> PhoneGap).
>> >>
>> >> I quite often have something like this:
>> >> - if not logged in then login
>> >> - get something from the remote server
>> >>
>> >> The issue is that the login is async and so is the get something,
>> >> currently I end up with code like this (contrived example):
>> >>
>> >> var _getSomething = function ()
>> >> {
>> >>    anAsyncCall( function(result) {
>> >>      doSomethingWith(result);
>> >>    });
>> >> }
>> >>
>> >> if (!loggedIn)
>> >> {
>> >>    login( function () {
>> >>      _getSomething();
>> >>    }
>> >> }
>> >> else
>> >> {
>> >>    _getSomething();
>> >> }
>> >>
>> >> ... I'm putting the "getSomething" into a closure to not repeat the
>> >> same
>> >> code (in reality there's usually a few more lines that happen as a
>> >> result of
>> >> the async call).
>> >>
>> >> It works, but in the interests of efficiency is there a better pattern
>> >> for
>> >> doing this? It just seems a bit clunky and you end up with a bunch of
>> >> if /
>> >> elses that can be hard to follow..
>> >>
>> >> Look forward to seeing what you all think!
>> >>
>> >> - Marcin
>> >>
>> >> --
>> >> M.
>> >
>> >
>
>
>
>
> --
> Josh Street
>
> http://josh.st/
> +61 (0) 425 808 469

Re: [sydjs] Callbacks and patterns question

From:
Jonathon Creenaune
Date:
2012-07-09 @ 03:08
http://ejohn.org/blog/how-javascript-timers-work/ is good if your
setTimeout-fu is lacking.

Re: [sydjs] Callbacks and patterns question

From:
Vince Panuccio
Date:
2012-07-10 @ 01:54
Hi Marcin,

I would probably use the publish/subscribe pattern in this instance. It
will remove those "clunky" if/else statements, avoid duplication of code
and more importantly, decouple the "doSomething" from the login
functionality. These are cross cutting concerns.

There's a library that I like in particular but you could easily roll your
own.

https://github.com/federico-lox/pubsub.js

Vince

On 8 July 2012 12:06, Marcin Szczepanski <marcins@gmail.com> wrote:

> I don't really know how to search for what I'm trying to ask, so I'll
> throw it out to the list for advice.
>
> The project I am working on involves a lot of async calls (both to
> external services and WebSQL - it's a mobile app wrapped with PhoneGap).
>
> I quite often have something like this:
> - if not logged in then login
> - get something from the remote server
>
> The issue is that the login is async and so is the get something,
> currently I end up with code like this (contrived example):
>
> var _getSomething = function ()
> {
>    anAsyncCall( function(result) {
>      doSomethingWith(result);
>    });
> }
>
> if (!loggedIn)
> {
>    login( function () {
>      _getSomething();
>    }
> }
> else
> {
>    _getSomething();
> }
>
> ... I'm putting the "getSomething" into a closure to not repeat the same
> code (in reality there's usually a few more lines that happen as a result
> of the async call).
>
> It works, but in the interests of efficiency is there a better pattern for
> doing this? It just seems a bit clunky and you end up with a bunch of if /
> elses that can be hard to follow..
>
> Look forward to seeing what you all think!
>
> - Marcin
>
> --
> M.
>

Re: [sydjs] Callbacks and patterns question

From:
Amos Shapira
Date:
2012-07-10 @ 01:57
I just wanted to thank you all for your tips on this thread.

As a JavaScript newcomer (I'm reading "The Good Parts" now) I find these
tips, written from experience, very useful.

Thanks.

--Amos

On 10 July 2012 11:54, Vince Panuccio <panuccio.vince@gmail.com> wrote:

> Hi Marcin,
>
> I would probably use the publish/subscribe pattern in this instance. It
> will remove those "clunky" if/else statements, avoid duplication of code
> and more importantly, decouple the "doSomething" from the login
> functionality. These are cross cutting concerns.
>
> There's a library that I like in particular but you could easily roll your
> own.
>
> https://github.com/federico-lox/pubsub.js
>
> Vince
>
> On 8 July 2012 12:06, Marcin Szczepanski <marcins@gmail.com> wrote:
>
>> I don't really know how to search for what I'm trying to ask, so I'll
>> throw it out to the list for advice.
>>
>> The project I am working on involves a lot of async calls (both to
>> external services and WebSQL - it's a mobile app wrapped with PhoneGap).
>>
>> I quite often have something like this:
>> - if not logged in then login
>> - get something from the remote server
>>
>> The issue is that the login is async and so is the get something,
>> currently I end up with code like this (contrived example):
>>
>> var _getSomething = function ()
>> {
>>    anAsyncCall( function(result) {
>>      doSomethingWith(result);
>>    });
>> }
>>
>> if (!loggedIn)
>> {
>>    login( function () {
>>      _getSomething();
>>    }
>> }
>> else
>> {
>>    _getSomething();
>> }
>>
>> ... I'm putting the "getSomething" into a closure to not repeat the same
>> code (in reality there's usually a few more lines that happen as a result
>> of the async call).
>>
>> It works, but in the interests of efficiency is there a better pattern
>> for doing this? It just seems a bit clunky and you end up with a bunch of
>> if / elses that can be hard to follow..
>>
>> Look forward to seeing what you all think!
>>
>> - Marcin
>>
>> --
>> M.
>>
>
>


-- 
 [image: View my profile on LinkedIn]
<http://www.linkedin.com/in/gliderflyer>