Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Conjuring JQuery Deferred with monadic incantations

Inspired by this (excellent) discussion of using Promises in javascript, I'm trying to work out how I could use Deferred to chain together async and non-async functions, to avoid paying the callback tax when using my 'Global storage' code.

I've got a few questions related to this, but I'll ask them together here, because the context is the same.

One thing I can't work out is how I can make a deferred out of something that isn't asynchronous - that is, how do I take a value, wrap it in a promise, and return it directly? (a -> M<a>)

Also, how can I take an asynchronous function and wrap it so that it returns its result directly, but wrapped in a promise? ((a -> b) -> (a -> M<b>))

Last question, for monadic freaks - is there a standard name for this function? [a] -> (a -> M<b>) -> M<[b]>

like image 236
Benjol Avatar asked Apr 06 '11 16:04

Benjol


2 Answers

Wrapping a value into a promise is as simple as using $.when:

var promise = $.when( value );

Also, as of jQuery 1.6, you have a very simple chaining method (pipe):

var chained = functionThatReturnsAPromise().pipe(function( resolveValue ) {
        return functionThatReturnsAnotherPromise( resolveValue );
    });

chained.done(function() {
    // Both asynchronous operations done in sequence
});

Hope this helps.

like image 75
Julian Aubourg Avatar answered Sep 30 '22 10:09

Julian Aubourg


I think the way that you'd turn a value into a Promise is to just "pre-succeed" the Deferred:

function v2p(value) {
  var rv = $.Deferred();
  rv.resolveWith(null, [value]);
  return rv.promise();
}

Now passing a function to ".done()" will result in the function being immediately called with the value.

v2p("hello").done(function(value) { alert(value); });

would immediately alert "hello".

like image 37
Pointy Avatar answered Sep 30 '22 08:09

Pointy