2013-04-23 4 views
3

Я написал помощник обратного вызова, которая позволяет мне группа нескольких обратных вызовов в одной функции переменные:Есть ли лучший способ сделать цепочку обратного вызова в javascript?

function chainCallbacks() { 
    var callbacks = arguments; 
    return function() { 
     for(var i = 0; i < callbacks.length; i++) { 
      if(callbacks[i] != null) { 
       callbacks[i].apply(null, arguments); 
      } 
     } 
    }; 
} 

это работает, но мне интересно, если есть какая-либо JavaScript библиотеки, которые предоставляют такую ​​же функциональность? или даже лучше, что-то, что имитирует шаблон «события» .NET?

myEvent+=myCallback; 
+0

http://stackoverflow.com/q/3249646/139010 –

+0

Глядя на ваше решение, они кажутся синхронными (или, по крайней мере, им не нужно ждать друг друга), так зачем вам нужен подход например, или библиотеку? Вы можете просто передать функцию, которая вызывает обратные вызовы. –

+0

@mat ball: я не думаю, что ваша ссылка связана ....?!?! – JasonS

ответ

1

Если вы хотите заменить функцию обратного вызова с одним, который вызывает оригинал, а также некоторые другие, я бы, наверное, просто сделать что-то вроде этого:

Requirejs.config.callback = function(orig) { 
    var fns = [orig, first, second, third]; 
    return function() { 
     fns.forEach(function(fn) { fn.apply(null, this); }, arguments); 
    }; 
}(Requirejs.config.callback); 

Но если вы» Повторяю это часто, я думаю, что ваше решение будет таким же хорошим, как и получается. Я не вижу необходимости в библиотеке.

Requirejs.config.callback = chainCallbacks(Requirejs.config.callback, first, second, third) 

Библиотека не может ничего сделать для расширения синтаксиса языка в JavaScript. Он ограничен тем, что доступно ... нет перегрузки оператора или чего-то еще.

2

Я изменил вашу функцию chainCallbacks. Вы можете проверить код ниже в консоли JS (я использую Chrome -works fine) и проверить результат.

var result = 0; 

function a() { 
     result += 5; 
     console.log(result); 
     _next(); 
} 

function b() { 
     result += 10; 
     console.log(result); 
     _next(); 
} 

function c() { 
     result += 20; 
     console.log(result); 
     _next(); 
} 

function chainCallbacks() { 

    var _this = this; 
    var _counter = 0; 
    var _callbacks = arguments; 

    var _next = function() { 
     _counter++; 
     if(_counter < _callbacks.length) { 
      _callbacks[_counter].apply(_this); 
     } 
    }; 

    _this._next = _next; 

    return function() { 
     if(_callbacks.length > 0) { 
      _callbacks[0].apply(_this); 
     } 
    }; 
} 

var queue = chainCallbacks(a, b, c); 
queue(); 

Идея проста - вы называете _next() всякий раз, когда ваша функция завершит выполнение, и вы хотите, чтобы перейти к другому. Таким образом, вы можете позвонить _next(), например. после некоторой анимации jQuery, и таким образом вы сохраните порядок функций.

+0

не могли бы вы объяснить, почему нужно добавить _next()? Я вижу, что это полезно для асинхронного выполнения, но добавляет сложности (вызываемая функция должна знать о функции chainCallbacks._next) – JasonS

+2

Точно - это полезно в случае асинхронных операций.Я думал, что это так, так как в другом случае вы можете использовать простой 'array' как очередь FIFO. Затем используйте метод' push' для добавления новых элементы и 'shift' для удаления и возврата первого элемента (' pop' для удаления и возврата, чтобы вести себя как простой стек [LIFO]). – Karol

Смежные вопросы