这是我通过修改实际核心代码$.when()
来使用您的语义制作的 jQuery 插件。想要一个更好的名字,它被称为$.myWhen()
:
(function($) {
$.myWhen = function( subordinate /* , ..., subordinateN */ ) {
var i = 0,
responseValues = Array.prototype.slice.call( arguments ),
length = responseValues.length,
// the count of uncompleted subordinates
remaining = length !== 1 || ( subordinate && jQuery.isFunction( subordinate.promise ) ) ? length : 0,
// the master Deferred. If responseValues consist of only a single Deferred, just use that.
deferred = remaining === 1 ? subordinate : jQuery.Deferred(),
// Update function for all resolve, reject and progress values
updateFunc = function( i, contexts, values ) {
return function( value ) {
contexts[ i ] = this;
values[ i ] = arguments.length > 1 ? Array.prototype.slice.call( arguments ) : value;
if( values === progressValues ) {
deferred.notifyWith( contexts, values );
} else if ( !( --remaining ) ) {
deferred.resolveWith( contexts, values );
}
};
},
progressValues, progressContexts, responseContexts;
// add listeners to Deferred subordinates; treat others as resolved
if ( length > 1 ) {
progressValues = new Array( length );
progressContexts = new Array( length );
responseContexts = new Array( length );
for ( ; i < length; i++ ) {
if ( responseValues[ i ] && jQuery.isFunction( responseValues[ i ].promise ) ) {
responseValues[ i ].promise()
.always( updateFunc( i, responseContexts, responseValues ) )
.progress( updateFunc( i, progressContexts, progressValues ) );
} else {
--remaining;
}
}
}
// if we're not waiting on anything, resolve the master
if ( !remaining ) {
deferred.resolveWith( responseContexts, responseValues );
}
return deferred.promise();
};
})(jQuery);
只需将此代码放在您加载 jQuery 的位置之后,该$.myWhen()
函数就会与$.when()
. 除了语义之外,其他一切都是 100% 完全相同的。