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" );

/*

Виведення:
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 або ви просто бажаєте просунутися в її вивченні, рекомендуємо вам переглянути курс, в якому зібрана вся теорія щодо даного фреймворку:

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

Від РЕБ до «плащів-невидимок»: за рік в рамках Brave1 створили 1 671 інноваційну розробку

За рік в рамках defense-tech кластеру Brave1 963 розробники створили 1 671 інноваційну розробку —…

29.04.2024

Треба «дешева» робоча сила: Google повністю звільнила команду Python в США

Корпорація Google звільнила всю команду Python в США. Про це стало відомо з публікації Social.coop…

29.04.2024

Українські школярі перемогли на міжнародному ШІ-хакатоні зі застосунком для вивчення жестової мови

Команда з ліцею КПІ PL of KPI Igor Sikorsky перемогла на міжнародному хакатоні зі штучного…

29.04.2024

Більше 50% Go i Ruby розробників з досвідом 3+ роки найняли на $5000. PHP — на самому дні

Більше половини Go i Ruby розробників з досвідом 3+ роки найняли на $5000 або більше.…

26.04.2024

Програмісти намагалися втекти з України в Молдову, щоб влаштуватись на роботу

Прикордонники недалеко від с. Кучурган Одеської області затримали двох програмістів, які намагалися втекти з України…

26.04.2024

В Україні запускають безплатне навчання блокчейн-розробці на Solana

Українське Solana-комʼюніті Kumeka Team з 7 травня запускає безплатне навчання блокчейн-розробці — Solana BootCamp. Про…

26.04.2024