做者:zhangl
原文:jQuey之Callbacks實現javascript
jQuery.myCallbacks = function () {
// 這裏主要是options參數爲'once;memory;once memory'
// 獲取options
var options = arguments[0] || '';
// 蒐集fire被調用時,傳入的參數
var arg = [];
// 蒐集add傳入的函數
var list = [];
// 判斷cb是否調用過fire
var isFired = false;
// 當前fire調用的函數索引
var fireIndex = 0;
function fire() {
// 循環執行add添加的函數
for (; fireIndex < list.length; fireIndex++) {
list[fireIndex].apply(window, arg);
}
// 若是options是once,清空list數組
if (options.indexOf('once') !== -1) {
list.length = 0;
fireIndex = 0;
}
}
return {
add: function (func) {
list.push(func);
// options爲memory而且fire被調用用過
if (options.indexOf('memory') !== -1 && isFired) {
fire();
}
return this;
},
fire: function () {
arg = arguments;
isFired = true;
fireIndex = 0;
fire();
}
};
};
複製代碼
jQuery.myDeferred = function () {
var arrCallbacks = [
[jQuery.Callbacks('once memory'), 'done', 'resolve'],
[jQuery.Callbacks('once memory'), 'fail', 'reject'],
[jQuery.Callbacks('memory'), 'progress', 'notify']
];
var deferred = {};
// 是不是pending狀態
var isPending = true;
for (var i = 0; i < arrCallbacks.length; i++) {
// deferred綁定done, fial, progress API
deferred[arrCallbacks[i][1]] = (function (index) {
return function (func) {
arrCallbacks[i][0].add(func);
}
})(i);
// deferred綁定resolve, reject, notify API
deferred[arrCallbacks[i][2]] = (function (index) {
return function () {
if (isPending) {
arrCallbacks[i][0].fire.apply(window, arguments);
arrCallbacks[i][2] === 'resolve' || arrCallbacks[i][2] === 'reject' ? isPending = false : '';
}
}
})(i);
}
return deferred;
};
複製代碼