Skip to content

Instantly share code, notes, and snippets.

@trevorparscal
Last active August 29, 2015 14:10
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 trevorparscal/bb598dddbba72e54843f to your computer and use it in GitHub Desktop.
Save trevorparscal/bb598dddbba72e54843f to your computer and use it in GitHub Desktop.
Promisification utilities for OOjs UI
// Sycnhronous before
MyClass.prototype.doSomething = function () {
// do something synchronously after parent method that may or may not return a promise
this.test = 1;
return OO.ui.promisify( MyClass.super.prototype.doSomething ).call( this );
};
// Sycnhronous after
MyClass.prototype.doSomething = function () {
return OO.ui.promisify( MyClass.super.prototype.doSomething ).call( this ).then( function () {
// do something synchronously after parent method that may or may not return a promise
this.test = 1;
} );
};
// Sycnhronous before
MyClass.prototype.doSomething = function () {
// do something synchronously after parent method that may or may not return a promise
this.doSomethingAsync( 'test' )
.then( OO.ui.promisify( MyClass.super.prototype.doSomething.bind( this ) );
};
// Sycnhronous after
MyClass.prototype.doSomething = function () {
return OO.ui.promisify( MyClass.super.prototype.doSomething ).call( this ).then( function () {
// do something synchronously after parent method that may or may not return a promise
return this.doSomethingAsync( 'test' );
} );
};
/**
* Wrap a function to execute later.
*
* If the given function returns a promise, the returned function will return a chained promise.
* Otherwise the returned function will return a promise resolved with the result of calling the
* given function.
*
* @param {Function} func Function to call later
* @param {Number} [time] Time to wait before calling the function, if omitted will execute after
* the call stack clears
* @throws {Error} If `func` is not a function
* @return {jQuery.Promise} Chained promise of the one returned by calling `func` or a promise
* resolved with result of calling func
*/
OO.ui.delay = function ( func, time ) {
if ( typeof func !== 'function' ) {
throw new Error( 'Cannot promisify; function expected' );
}
return function () {
var args = Array.prototype.slice.call( arguments ),
deferred = $.Deferred();
setTimeout( function () {
var res = func.apply( this, Array.prototype.slice.call( arguments ) );
if ( res && typeof res.promise === 'function' ) {
res.then( deferred.resolve, deferred.reject, deferred.notify );
} else {
deferred.resolve( res );
}
}, time );
return deferred.promise();
};
};
/**
* Wrap a function to always return a promise.
*
* If the given function returns a promise, the returned function will also return that promise.
* Otherwise the returned function will return a promise resolved with the result of calling the
* given function.
*
* @param {Function} func Function to promisify
* @throws {Error} If `func` is not a function
* @return {jQuery.Promise} Promise returned by calling `func` or promise already resolved with
* result of calling func
*/
OO.ui.promisify = function ( func ) {
if ( typeof func !== 'function' ) {
throw new Error( 'Cannot promisify; function expected' );
}
return function () {
var args = Array.prototype.slice.call( arguments ),
res = func.apply( this, args );
if ( res && typeof res.promise === 'function' ) {
return res;
}
return $.Deferred().resolve( res ).promise();
};
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment