Follow-up 8250c8ad54: unbreak ApiResponseCache

.set() should not overwrite existing deferreds; instead,
it should resolve the existing deferred if it's pending.
This is necessary because .set() is used by processResult().
Without this, passing .get() a title that no information
is known for results in a promise that is never resolved,
because the associated deferred is overwritten as soon
as the API response arrives.

Still make .set() a no-op if data has already been set,
by checking if the deferred is pending. For .resolve() this
doesn't matter, but for modifying this.cacheValues it does.

Bug: T107212
Change-Id: I70e8c5450f23062db214ccc5c585624d41de6509
This commit is contained in:
Roan Kattouw 2015-07-28 15:02:32 -07:00
parent 12d22fe48a
commit 6d22fd1aa7

View file

@ -109,7 +109,7 @@ ve.init.mw.ApiResponseCache.prototype.getCached = function ( name ) {
*/
/**
* Add entries to the cache.
* Add entries to the cache. Does not overwrite already-set entries.
*
* @param {Object} entries Object keyed by page title, with the values being data objects
* @fires add
@ -117,9 +117,13 @@ ve.init.mw.ApiResponseCache.prototype.getCached = function ( name ) {
ve.init.mw.ApiResponseCache.prototype.set = function ( entries ) {
var name;
for ( name in entries ) {
this.deferreds[name] = $.Deferred();
this.deferreds[name].resolve( entries[name] );
this.cacheValues[name] = entries[name];
if ( !Object.prototype.hasOwnProperty.call( this.deferreds, name ) ) {
this.deferreds[name] = $.Deferred();
}
if ( this.deferreds[name].state() === 'pending' ) {
this.deferreds[name].resolve( entries[name] );
this.cacheValues[name] = entries[name];
}
}
this.emit( 'add', Object.keys( entries ) );
};