jQuery.Callbacks(): что это такое и как с ним работать?

Сергій Бондаренко

Сегодня речь пойдет об объекте jQuery.Callbacks. Но, перед тем, как о нем поговорить, давайте вспомним, что такое коллбэк в JavaScript.

Зачем вообще нужны коллбэки?

Коллбэк в JavaScript — это функция, которую мы передаем в качестве аргумента другой функции. 

Для чего они нужны? Предположим, у вас есть HTML-разметка, в которой вы, используя CSS-селектор, определили какой-то элемент в DOM (в примере это селектор out). 

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Тест для понимания callback</title>
    </head>
<body> 
<div id='out'> the place for text </div>
</body>
 <script src="script.js">
    </script>
</html>

Напишем простую функцию, которая будет обращаться к этому элементу и публиковать вместо него элементы массива.

function myFunc(callback) {
    const massiv = [3, 56, 7];
        let element = document.querySelector("#out");
    callback(element, massiv);
}
function outprint1(elem, arr) {
    elem.innerHTML = arr.join('---');
}
myFunc(outprint1);

Функция outprint1 — коллбэк, поскольку она передана в качестве аргумента в функцию обработки массива myFunc.

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

function myFunc(tram) {
    const massiv_znachenii = [117, 556, 709];
    let element = document.querySelector("#out");
    tram(element, massiv_znachenii);
}
function out1(element_massiva, array) {
    element_massiva.innerHTML = array.join('---');
}
function out2(elem, arr) {
    elem.innerHTML = arr.join('***');}
myFunc(out1);

Указав в качестве аргумента уже другую функцию myFunc(out2), мы получим вывод элементов массива через три звездочки. Таким образом коллбэк как бы разделяет код и упрощает понимание выполняемых действий. 

Функции, которые вызываются для реализации какого-то события — обычное дело в JavaScript. Примером такого обращения могут служить запросы AJAX. В этом случае появляется необходимость вызвать не одну функцию, а сразу список, который может состоять из десятков функций обратного вызова. Вот, например, как выглядит реализация паттерна Observer:

class Observable {
constructor() {
this.listeners = {};
}

// сделать подписку
on(e, callback) {
if (this.listeners[e] == undefined) {
            this.listeners[e] = {};

    this.listeners[e].eventProperty = {};
    this.listeners[e].eventProperty.isOnOnce = false;
    this.listeners[e].data = [];
        }
this.listeners[e].data.push(callback);
}

// Осуществить единоразовую подписку
onOnce(e, callback) {
this.on(e, callback);
this.listeners[e].eventProperty.isOnOnce = true;
}

// Отменить подписку.
off(e, callback) {
this.listeners[e].data = this.listeners[e].data.
filter(function (listener) { return listener !== callback; });
}

// Сделать рассылку сообщени
emit(e, data) {
if (this.listeners[e] == undefined || this.listeners[e].data == undefined) {
return;
}

let itObj = this;
this.listeners[e].data.forEach(listener => {
if(itObj.listeners[e].eventProperty.isOnOnce) {
itObj.off(e, itObj.listeners[e].data[0]);
}
listener(data);
});
}
}

Если вы ищете мощный способ управления списками коллбэков — это объект jQuery.Callbacks.

Объект jQuery.Callbacks можно найти внутри jQuery.Deferred и jQuery.ajax. Он создается вызовом конструктора jQuery.Callbacks(flags). Параметр flags влияет на опции работы объекта и является необязательным.

Для добавленного объекта callbacks можно указывать списки коллбэк-функций. Также можно выполнять различные манипуляции:

  • удалять функции обратного вызова;
  • обращаться к функциям обратного вызова;
  • делать повторный вызов;
  • сверять статус объекта (сделан ли вызов или пока нет).

Для этого задействуются соответствующие методы объекта — add(), remove(), fire() и другие.

Применение коллбэков осуществляется по порядку очереди в группе.

Методы, поддерживаемые $.Callbacks()

Функция $.Callbacks() используется для обеспечения базовой функциональности jQuery $.ajax() и $.Deferred() компонентов. $.Callbacks() поддерживает набор методов, включая:

  • callbacks.add() — добавление обратного вызова или набора обратных вызовов в список коллбэков;
  • callbacks.remove() — удаляет коллбэк или группу коллбэков из списка;
  • callbacks.empty() — удаляет все обратные вызовы из списка;
  • callbacks.disable() — метод для выключения списка обратного вызова или запрета выполнения с ним других действий;
  • callbacks.disabled() — определяет, отключен ли список коллбэков;
  • callbacks.fire() — вызывает все обратные вызовы с заданными аргументами;
  • callbacks.fireWith() — вызов всех коллбэков в списке с заданным контекстом и аргументами.

Примеры управления списками

Ниже приведены две функции с именами myfunc1 и myfunc2:

function myfunc1( value ) {
    console.log( value );
  } 
  function myfunc2( value ) {
    console.log( "myfunc2 says: " + value );
    return false;
  }

Их можно поместить в список $.Callbacks, а затем вызывать следующим образом:

 const callbacks = $.Callbacks();
  callbacks.add( myfunc1 );
     // Вывод: Highload!
  callbacks.fire( "Highload!" );
   callbacks.add( myfunc2 );
   // Вывод: Today!, myfunc2 says:Today!
  callbacks.fire( "Today!" );

В результате становится проще создавать сложные списки коллбэков, в которых входные значения могут быть легко переданы стольким функциям, скольким необходимо.

Другой поддерживаемый метод $.Callbacks— это .remove(), который позволяет удалить конкретный обратный вызов из списка обратных вызовов. Вот пример его использования:

const  callbacks = $.Callbacks();
callbacks.add( myfunc1 );
// Вывод: Highload!
callbacks.fire( "Highload!" );
callbacks.add( myfunc2 );
// Вывод: Today!, myfunc2 says: Today!
callbacks.fire( "Today!" );
callbacks.remove( myfunc2 );
// Выводится только Highload.Today!, поскольку myfunc2 удалена.
callbacks.fire( "Highload.Today!" );

Варианты поддерживаемых флагов

Флаги можно применять, ставя между ними пробел. Перечислим их.

$.Callbacks( “once” )

  • once — группа с коллбэками выполняется только один раз, а все последующие вызовы метода fire() ни к чему не приведут (по аналогии с объектом deferred):
const callbacks = $.Callbacks( "once" );
  callbacks.add( myfunc1 );
  callbacks.fire( "Highload!" );
  callbacks.add( myfunc2 );
  callbacks.fire( "Today" );
  callbacks.remove( myfunc2 );
  callbacks.fire( "HighloadToday" );

//Вывод: Highload!

$.Callbacks( “memory” )

  • memory — этот флаг означает, что необходимо запоминать параметры последнего вызова метода fire() (и выполнения коллбэков из списка) и немедленно выполнять добавляемые коллбэки с соответствующими параметрами, если они добавляются уже после вызова метода fire() (как это сделано в объекте deferred):
 const callbacks = $.Callbacks( "memory" );
  callbacks.add( myfunc1 );
  callbacks.fire( "Highload!" );
  callbacks.add( myfunc2 );
  callbacks.fire( "Today" );
  callbacks.remove( myfunc2 );
  callbacks.fire( "HighloadToday" );

/*

Вывод:
Highload!
myfunc2 says: Highload!
Today
myfunc2 says: Today
HighloadToday

*/

$.Callbacks( “unique” )

  • unique — при указании данного флага каждый коллбэк может быть добавлен в список только один раз. Если попробовать повторно добавить коллбэк в список, это ни к чему не приведет:
const  callbacks = $.Callbacks( "unique" );
 callbacks.add( myfunc1 );
 callbacks.fire( "Highload!" );
 callbacks.add( myfunc1 ); // Повторное добавление
 callbacks.add( myfunc2 );
 callbacks.fire( "Today" );
 callbacks.remove( myfunc2 );
 callbacks.fire( "Highload!Today" );

/*Вывод:

Highload!
Today
myfunc2 says: Today
Highload!Today

*/

$.Callbacks( “stopOnFalse” )

  • stopOnFalse — флаг говорит о том, что следует остановить выполнение коллбэков из списка, если какой-то из них вернул false, в пределах текущей сессии вызова fire(). Очередной вызов метода fire() открывает новую сессию запуска группы коллбэков. Они будут выполняться снова до тех пор, пока один из списка не вернет false либо пока не закончатся:
function myfunc1 ( value ) {
  console.log( value );
  return false;
}
 function myfunc2 ( value ) {
  myfunc1 ( "myfunc2  says: " + value );
  return false;
}
 const callbacks = $.Callbacks( "stopOnFalse" );
callbacks.add( myfunc1 );
callbacks.fire( "Highload!" );
callbacks.add( myfunc2 );
callbacks.fire( "Today" );
callbacks.remove( myfunc2 );
callbacks.fire( "Highload!Today" );

 /*

Вывод:
Highload!
Today
Highload!Today

*/

Комбинирование флагов $.Callbacks( ‘unique memory’ )

function myfunc1( value ) {
  console.log( value );
  return false;
}

 
function myfunc2( value ) {
  myfunc1( "myfunc2 says: " + value );
  return false;
}

const callbacks = $.Callbacks( "unique memory" );
callbacks.add( myfunc1 );
callbacks.fire( "Highload!" );
callbacks.add( myfunc1 ); // Повторное добавление
callbacks.add( myfunc2);
callbacks.fire( "Today" );
callbacks.add( myfunc2);
callbacks.fire( "ua" );
callbacks.remove( myfunc2);
callbacks.fire( "Highload!Today" );

/*

output:
Highload!
myfunc2 says: Highload!
Today
myfunc2 says:Today
ua
myfunc2 says: ua
Highload!Today

*/

Функции обратного вызова могут использоваться и при разработке различных анимационных эффектов. Обычно используется следующий синтаксис:

$ (селектор). Hide (скорость, обратный вызов);

Так, например, будет реализована задача, когда необходимо скрыть текст при нажатии на кнопку:

<!DOCTYPE html>
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.1/jquery.min.js"></script>
<script>
$(document).ready(function(){
  $("button").click(function(){
    $("p").hide("slow", function(){
      alert("Теперь текст спрятан");
    });
  });
});

</script>
</head>
<body>
<button>Hide</button>
<p>Highload.Today</p>
</body>
</html>

Заключение

Основной смысл функций JavaScript, который реализован в jQuery, состоит в том, чтобы обеспечить веб-разработчику удобное обращение к элементам документной модели DOM, к их атрибутам и значениям.

Надеемся, что теперь, используя объект jQuery.Callbacks в сложных проектах, вы по достоинству оцените его потенциал. Например, он будет уместен, если вы захотите сделать свой плагин для JQuery с большим количеством событий.

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

Останні статті

Обучение Power BI – какие онлайн курсы аналитики выбрать

Сегодня мы поговорим о том, как выбрать лучшие курсы Power BI в Украине, особенно для…

13.01.2024

Work.ua назвал самые конкурентные вакансии в IТ за 2023 год

В 2023 году во всех крупнейших регионах конкуренция за вакансию выросла на 5–12%. Не исключением…

08.12.2023

Украинская IT-рекрутерка создала бесплатный трекер поиска работы

Unicorn Hunter/Talent Manager Лина Калиш создала бесплатный трекер поиска работы в Notion, систематизирующий все этапы…

07.12.2023

Mate academy отправит работников в 10-дневный оплачиваемый отпуск

Edtech-стартап Mate academy принял решение отправить своих работников в десятидневный отпуск – с 25 декабря…

07.12.2023

Переписки, фото, история браузера: киевский программист зарабатывал на шпионаже

Служба безопасности Украины задержала в Киеве 46-летнего программиста, который за деньги устанавливал шпионские программы и…

07.12.2023

Как вырасти до сеньйора? Девелопер создал популярную подборку на Github

IT-специалист Джордан Катлер создал и выложил на Github подборку разнообразных ресурсов, которые помогут достичь уровня…

07.12.2023