Показать сообщение отдельно
  #1 (permalink)  
Старый 16.10.2011, 18:28
Аватар для Riim
Рассеянный профессор
Отправить личное сообщение для Riim Посмотреть профиль Найти все сообщения от Riim
 
Регистрация: 06.04.2009
Сообщений: 2,379

Упрощенный Deferred
Примерно тоже самое находиться в jQuery и Dojo, но здесь сильно упрощенный вариант (не продумана вероятность ошибок в обработчиках, нельзя указать контекст выполнения обработчиков и т. д.). Предназначен, чтобы разобраться, как это работает на простом примере и/или для допиливания (выкладывайте прямо здесь, что получается). Критика приветствуется.

/**
 * Id: deferred
 * */

(function() {

var arraySlice = [].slice;

function Deferred() {
	if (!(this instanceof Deferred)) {
		throw new TypeError();
	}
	this._then = [];
	this.then.apply(this, arguments);
}

Deferred.prototype = {
	_resolved: false,

	then: function _(callback) {
		if (callback) {
			if (this._resolved) {
				callback();
			} else {
				this._then.push(callback);
			}
		}
		if (arguments.length > 1) {
			_.apply(this, arraySlice.call(arguments, 1));
		}
		return this;
	},

	resolve: function() {
		if (!this._resolved) {
			this._resolved = true;
			var results = [], then = this._then, i = 0, l = then.length;
			while (i < l) {
				results[i] = then[i++].apply(null, arguments);
			}
			return results;
		}
	}
};

Deferred.when = function() {
	var dfr = new Deferred(), count = 0;
	function resolveFunc() {
		if (!--count) {
			dfr.resolve();
		}
	}
	for (var i = 0, l = arguments.length; i < l; ++i) {
		if (arguments[i]) {
			++count;
			arguments[i].then(resolveFunc);
		}
	}
	return dfr;
};

this.Deferred = Deferred;

})();

// пример использования:
var dfr1 = new Deferred(function() { console.log('dfr 1'); });
var dfr2 = new Deferred(function() { console.log('dfr 2'); });

Deferred.when(dfr1, dfr2).then(function() { console.log('dfr all'); });

setTimeout(function() { dfr1.resolve(); }, 2000);
setTimeout(function() { dfr2.resolve(); }, 5000);


UPD: полезные ссылки: 1, 2, 3, 4, 5.

Последний раз редактировалось Riim, 16.10.2011 в 18:40.
Ответить с цитированием