Skip to content

Instantly share code, notes, and snippets.

@rjgotten
Last active August 29, 2015 14:06
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save rjgotten/23c223a366862b7d1a8c to your computer and use it in GitHub Desktop.
Save rjgotten/23c223a366862b7d1a8c to your computer and use it in GitHub Desktop.
Wrapping can.Deferred as a can.compute
can.compute.when = function( computer ) {
var
promise,
combined,
result;
// Ensure that we always get back a then-able promise from `computer`,
// and that it is infact a `can.compute` and not a regular function.
promise = can.compute( function() { return can.when( computer()) });
// Promise should always be bound, to ensure its value is cached and
// we don't inadvertently start multiple expensive async operations.
promise.bind( "change", function(){});
combined = can.compute.async( null, function( oldValue, setValue ) {
var _promise = promise();
function handle( value ) {
// Guard against the underlying compute having switched over to a new
// result. In this case we should bail early as this callback is no
// longer relevant.
if ( _promise !== promise()) return;
setValue({
state : _promise.state(),
value : value
});
}
// Wrap in a timeout to ensure that promise resolution will *always* take place
// asynchronously.
setTimeout( function(){ _promise.then( handle, handle ) }, 1 );
// Always initially set state to pending as the `setValue` operation is set to
// complete inside a promise callback which, even if the promise is no longer
// pending, should still execute asynchronously.
return {
state : "pending",
value : undefined
}
});
result = can.compute( function(){ return combined().value; })
result.state = can.compute( function(){ return combined().state; })
return result;
}
var data {
foo : can.compute.when( function() {
return Foo.findOne({ id: 42 });
})
};
can.view( VIEW, data, function ( fragment ) {
this.element.append( fragment );
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment