understanding when.js: would this be correct way to wrap a sync method to become async?

95 views
Skip to first unread message

Geert-Jan Brits

unread,
Mar 7, 2013, 9:28:40 AM3/7/13
to cuj...@googlegroups.com
I'm developing a framework in which a particular set of functions could be developed (outside of my control) in a sync or async matter. 
In all cases I want to use promises, which is why in the event of an sync method I want to wrap them automatically in an async-function that behaves correctly (as for promise behavior) 

I first tried to find a way to guarantee if a method is async or sync, but that' s really brittle (test calling it on initialization to test if a promise is returned, etc... not bullet-proof) 

Second try is the following, in which I just wrap any method (sync or async), so no testing required. 

Still learning when.js (and getting used to promises in general) so I'd like to get your feedback if this approach would be suitable, see code below: 



var aspect = {
  f
: function(){
   
//function may be sync or async this is unknown.
 
}
 
};

 aspect
.f = (function (origf) {
   
return function(){
     
var deferred = when.defer();
     
when(origf, function(){
       deferred
.resolve();
     
}).otherwise(function(err){
       deferred
.reject(err);
     
});    
     return deferred.promise;
   
};
 
}(aspect.f));


To my understanding, whether a 'origf'' is async or not, this will create an async function that resolves correctly. 
Moreover an async 'origf' may do a reject() in which case the wrapper picks it up. 

still not sure, how to handle the case (out of my control) when an sync 'origf' throws an error (explicitly designed or unanticipated)
Even though I read Brian' s excellent reply to my post yesterday (uncaught exception in when() body disappears in void)  https://groups.google.com/forum/#!topic/cujojs/vIU6WCpVEfI

So in short, would this be a correct approach? And better yet, how to handle the 'sync 'origf' throw error' -case?

Thanks,
Geert-Jan

Brian Cavalier

unread,
Mar 7, 2013, 10:21:18 AM3/7/13
to cuj...@googlegroups.com
Great question.  I think the bind() method in when/function will do exactly what you want.  Although the docs don't explicitly say it, it handles sync and async (promise-returning) functions correctly.  It also allows the new, wrapped function to accept promises as parameters.  That's especially since it makes async functions composable via normal means.

Let me know if that'll work for you.  There are also several other methods in when/function, as well as the when/callbacks and when/node/function modules that provide similar methods for dealing with callback-based async functions, and node-style async functions.  There is a section in the docs that covers all 3 modules and their methods.  Enjoy!

b

Brian Cavalier

unread,
Mar 13, 2013, 11:12:48 PM3/13/13
to cuj...@googlegroups.com
Just a quick heads up that bind() is being renamed to lift() in when.js 2.0.  We'll keep the bind() alias, so your code won't break, but using lift() will be more future proof.
Reply all
Reply to author
Forward
0 new messages