zkrvndm
@zkrvndm
Архитектор решений

Как удалить обработчик прогресса в jQuery.Deferred?

В библиотеке jQuery имеется свой аналог промисов. Речь об объектах jQuery.Deferred. Основное отличие от промисов в более широком функционале, в частности, можно кроме обработчиков успеха / ошибки навешивать еще и обработчики прогресса:
var deferred = $.Deferred();

deferred.progress(function(n) {
    console.log('Температура сейчас: ' + n);
});

setTimeout(function() {
    deferred.notify('30 градусов.');
}, 3000);

Однако, мне совершенно непонятно как такие обработчики потом снимать, чтобы они не копились.

Пояснение зачем мне это надо
Архитектурно у меня предусмотрен основной поток (он вечный) и множество дочерних (пересоздаются постоянно), что время от времени будут подключатся и смотреть что там происходит в основном потоке. Однако, если дочерний поток завершил работу, то обработчик прослушиватель от него останется в Deferred основного потока и будет занимать ресурсы, что плохо.

Буду признателен за помощь.
  • Вопрос задан
  • 56 просмотров
Решения вопроса 1
zkrvndm
@zkrvndm Автор вопроса
Архитектор решений
Я выяснил, что при работе jQuery.Deferred используется jQuery.Callbacks. Это позволило написать обертку для jQuery.Deferred и вытащить возможность управления обработчиками наверх. Ниже пример.

(function() {
	
	var deferred_original = jQuery.Deferred;
	
	jQuery.Deferred = function() {
		
		var callbacks = [];
		
		var callbacks_original = jQuery.Callbacks;
		
		jQuery.Callbacks = function() {
			var callback = callbacks_original.apply(this, arguments);
			callbacks.push(callback);
			return callback;
		}
		
		var deferred = deferred_original.apply(this, arguments);
		deferred.callbacks = jQuery(callbacks);
		
		jQuery.Callbacks = callbacks_original;
		
		return deferred;
		
	}
	
})();

// Проверка:

var deferred = $.Deferred();

var callback = function(n) {
    console.log('Test ' +n);
}

deferred.progress(callback);

deferred.notify(1);

// Команда ниже успешно удалит обработчик прогресса:
deferred.callbacks.each(function(n, c) { c.remove(callback); });

deferred.notify(2);
Ответ написан
Комментировать
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы