[wp-trac] [WordPress Trac] #38889: Proposition to allow an api.Value() using asynchronous callbacks
WordPress Trac
noreply at wordpress.org
Mon Nov 21 16:50:20 UTC 2016
#38889: Proposition to allow an api.Value() using asynchronous callbacks
-------------------------+-----------------------------
Reporter: nikeo | Owner:
Type: enhancement | Status: new
Priority: normal | Milestone: Awaiting Review
Component: Customize | Version: trunk
Severity: normal | Keywords:
Focuses: javascript |
-------------------------+-----------------------------
When an `api.Value` instance is set to a new value, we might need to wait
for all callbacks to be completed or resolved before actually doing
something else.
With the current implementation, if an `api.Value` has asynchronous
callbacks, there's no way to know when it's resolved after a `set()`
action. Any further dependant actions would have to be done after an
hazardous delay.
The following is a proposition to solve this by adding an optional `{
deferred : true }` param when binding a callback to an `api.Value`
instance.
This way, a syntax like this could be used :
{{{
//let's declare a new api Value().
api.observable_value = new api Value( 'initial' );
//this is basic callback with a $.Deferred callback
var fakeAjaxCall = function( to, from ) {
var dfd = $.Deferred();
_.delay( function() {
console.log( 'I am a fake ajax call.');
dfd.resolve( to );
}, 2000 );
return dfd.promise();
};
//let's bind the Value instance with this callback and inform it that it
is a deferred action
api.observable_value.bind( fakeAjaxCall, {deferred : true } );
//now let's set update the value
api.observable_value.set( 'new_val' ).done( function() {
//do something with this new_val when all callbacks are done
console.log('All callbacks are done now, we can use the new val in
further dependant actions : ', this() );
});
}}}
This could be useful for callbacks involving preview refreshs ( if the
preview returns a `promise()` , see #38797), or media fetched in ajax in
db.
'''Code'''
This is a proposition of modification of the `api.Value` constructor, in
the current customize-base.js file. ( as of 4.7 beta-3 )
The code introduces an optional additional collection of `$.Deferred`
functions, as a property of the `api.Value` constructor.
{{{
/**
* Set the value and trigger all bound callbacks.
* @return a promise onto which it is attached the current 'this' of the
api.Value, when all callbacks are resolved.
* @param {object} to New value.
*/
set: function( to ) {
var from = this._value, dfd = $.Deferred(), self = this, _promises =
[];
to = this._setter.apply( this, arguments );
to = this.validate( to );
// Bail if the sanitized value is null or unchanged.
if ( null === to || _.isEqual( from, to ) ) {
return this;
}
this._value = to;
this._dirty = true;
if ( this._deferreds ) {
_.each( self._deferreds, function( _prom ) {
_promises.push( _prom.apply( null, [ to, from ] ) );
});
$.when.apply( null, _promises )
.then( function() {
self.callbacks.fireWith( self, [ to, from ] );
dfd.resolveWith( self, [ to, from ] );
});
} else {
this.callbacks.fireWith( this, [ to, from ] );
return dfd.resolveWith( self, [ to, from ] ).promise( self );
}
return dfd.promise( self );
}
/**
* Bind a function to be invoked whenever the value changes.
*
* @param {...Function} A function, or multiple functions, to add to the
callback stack.
* @param { deferred : true } let us decide if the callback(s) have to be
populated as $.Callbacks or $.Deferred
*/
bind: function() {
var self = this,
_isDeferred = false,
_cbs = [];
$.each( arguments, function( _key, _arg ) {
if ( ! _isDeferred )
_isDeferred = _.isObject( _arg ) && _arg.deferred;
if ( _.isFunction( _arg ) )
_cbs.push( _arg );
});
if ( _isDeferred ) {
self._deferreds = self._deferreds || [];
_.each( _cbs, function( _cb ) {
if ( ! _.contains( _cb, self._deferreds ) )
self._deferreds.push( _cb );
});
} else {
//original method
self.callbacks.add.apply( self.callbacks, arguments );
}
return this;
}
}}}
The `unbind` method of the `api.Value` constructor is missing here, it
should also be modified.
Any thoughts or feedbacks are welcome !
--
Ticket URL: <https://core.trac.wordpress.org/ticket/38889>
WordPress Trac <https://core.trac.wordpress.org/>
WordPress publishing platform
More information about the wp-trac
mailing list