Возможно знать, когда все драйверы событий закончатся?

Я хочу знать, когда все драйверы событий в событии в языке сценариев JavaScript закончатся. Это возможное?

Пример:

<button id='button' ...>Submit</button>
<script>
   ultimo = notify() {
       alert("Último!");
   };
   $( '#button' ).on('click', function() { alert('Primero') });
   $( '#button' ).on('click', function() { alert('Segundo') });
   $( '#button' ).on('click', ultimo );
</script>

С этим кодом, я буду получать 3 типа бдительности: Первый, Второй и Последний.

Но последний, может быть, не был последним, если есть код в другой стороне, которая добавляет другие драйверы.

Тогда: есть способ знать, когда все драйверы события закончатся?

Чтобы быть более специфическим, я пишу библиотеку, и хочу сделать что-то в событии, но только после всех драйверов, которые могут быть добавленными пользователей моей библиотеки.

6
задан 03.01.2016, 17:32
3 ответа

Есть возможный выбор, основанный на этом вопросе сайта на английском (и в частности в ответах dowski и Аврама Лэвински), используя персонализированные события, метаданные, которых jQuery он предоставляет с $._data(), и зная, что события работают в порядке, к которому они ассоциировались с элементом.

Идея (которая только функционировала бы с событиями, присоединенными с jQuery) была бы следующей:

  • Создавать персонализированное событие (мы будем помещать его имени afterclick) и добавлять к нему весь код, который ты хочешь, чтобы он работал, закончив clicks.
  • ДО ТОГО, КАК никакое событие не присоединилось к элементу, присоединять твой собственный детектор click, который:

    1. Предотвратите распространение события немедленного способа (даже не следующие clicks). Это может делаться с stopImmediatePropagation().
    2. Выполните все функции, ассоциируемые с событием click в команде (возможно получать array с этими функциями используя $._data(this, "events").click).
    3. Попросите выполнение персонализированного события.

На простой вид покажись простым: нет? И код не был бы очень сложным также:

// asociamos un event listener con el elemento
// MUY IMPORTANTE: esto debe ejecutarse antes de que cualquier otro event listener se añada
$(elemento).on("click", function(e) {
  if (e) {
    // prevenimos la propagación del resto de eventos click
    e.stopImmediatePropagation();

    // obtenemos una lista con las acciones asociadas al evento click
    var lectoresEvento = $._data(this, "events").click;

    // para cada elemento de la lista
    for (var x = 0; x < aClickListeners.length; x++) {
      // ejecutar la función
      aClickListeners[x].handler();
    }

    // invocar el evento personalizado afterclick
    $(this).trigger("afterclick")
  }
});

Идея состояла бы в том, чтобы выполнять этот код в твоей библиотеке, нагрузив jQuery и перед тем, как загружать любой другой код. Ниже будет возможно присоединять (или не) событие afterclick в различные элементы.

Персонализированное событие будет работать всегда в конце всех clicks; и если нет ни одного, он будет работать в любом случае (что-то подобное finally в исключениях).


Преимущества этого метода:

  • Функционируй :P
  • Ты не нуждаешься в том, чтобы не знать ни, сколько драйверов событий были созданы, ни Ваше имя. Все окажутся упорядоченными в списке $._data().

Недостатки этого метода:

  • Только функционируй внутри вселенной jQuery.
  • $._data(this, "events") оно не функционирует в версиях, предыдущих 1.8, для этих было бы нужно изменять немного код и использовать element.data('events') (как он объясняется в этом вопросе сайта на английском).

Здесь я оставляю пример (могут быть видны результаты в консоли):

// Asociamos un evento click a todos los elementos
$("*").on("click", function(e) {
  if (e) {
    e.stopImmediatePropagation();
    var lectoresClick = $._data(this, "events").click;
    for (var x = 0; x < lectoresClick.length; x++) {
      lectoresClick[x].handler();
    }
    $(this).trigger("afterclick");
  }
});

// definimos las acciones que se ejecutarán después de todas las acciones del evento click
$("button").on("afterclick", function() { 
  console.log("Ejecutados todos los eventos click de " + $(this).attr("id")); 
});

// asociamos diferentes acciones al evento click de los botones
$("#Boton1").on("click", function() { console.log("Primer evento botón 1"); });
$("#Boton2").on("click", function() { console.log("Primer (y único) evento botón 2"); });
$("#Boton1").on("click", function() { console.log("Segundo evento botón 1"); });
$("#Boton1").on("click", function() { console.log("Tercer evento botón 1"); });
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>

<button id="Boton1">Botón 1</button>
<button id="Boton2">Botón 2</button>
<button id="Boton3">Botón 3</button>
1
ответ дан 24.11.2019, 15:02

Ты можешь использовать Promises:

<!DOCTYPE html>
<html>
    <head>
    </head>
    <body>
        <button id="button">Submit</button>
        <script src="http://code.jquery.com/jquery-2.1.4.min.js"></script>
        <script type="text/javascript">
            $(document).ready(function() {
                $("#button").on("click", todo);

            });

            function todo() {
                Promise.all([primero(), segundo(), ultimo()]).then(function(values) {
                    alert("Terminado: " + values);
                });
            }

            function primero() {
                return new Promise(function(resolve, reject) {
                    console.log("Primero");
                    resolve(1);
                });

            }

            function segundo() {
                return new Promise(function(resolve, reject) {
                    setTimeout(resolve, 2000, 2);
                });
            }

            function ultimo() {
                return new Promise(function(resolve, reject) {
                    console.log("Ultimo");
                    resolve(3);
                });
            }
        </script>
    </body>
</html>

Я использую Promise.all что ждет конец или отталкивание одного Array Promises.

Каждая из функций, которые называются внутри функции todo возврати обещание:

return new Promise(function(resolve, reject) { ... });

Функция segundo опоздай большее время, чем другие два но функция todo подожди окончание всех их.

0
ответ дан 24.11.2019, 15:02
  • 1
    Это одинокое функционирует, если я контролирую все c и # 243; я говорю. Если другой c и # 243; я говорю в и # 241; ada драйвер события, этот м и # 233; все не будет помогать мне знанию, если он закончился, правда? – Flimzy 03.01.2016, 17:20
  • 2
    @Flimzy и #191; в qu и # 233; ты относишься с " другой c и # 243; я говорю в и # 241; ada"?, и #191; podr и # 237; схвати помещать пример в твой вопрос? – César 03.01.2016, 17:27
  • 3
    foo.js он делает $(x).on('click', ...), и tambi и # 233; n bar.js он делает $(x).on('click', ...). Это очень com и # 250; n, если ты считаешь delegaci и # 243; n событий... и библиотеки (и в самом деле, я пишу библиотеку, и пользователи должны быть способны в и # 241; adir драйверы событий tambi и # 233; n. В самом деле, это это вся точка моего вопроса: Я хочу узнать, что драйверы пользователей уже закончились). – Flimzy 03.01.2016, 17:29
  • 4
    Я издал мой вопрос, чтобы быть м и # 225; s я определяю с этими деталями. – Flimzy 03.01.2016, 17:32
  • 5
    @Flimzy я понимаю, хороший в этом случае мой ответ не помогает тебе совсем, tendr и # 237; эксперт, который знать каковы это все эти драйверы, чтобы добавлять их к array, когда ты называешь Promise.all – César 03.01.2016, 17:37

Используй Async

async.series([
  function(callback) {
    callback(null, 'uno');
  },
  function(callback) {
    callback(null, 'dos');
  },
  function(callback) {
    callback(null, 'ultimo');
  }
], function (err, result) {
  // ['uno', 'dos', 'ultimo']
});

PodrГ-Схвати помещать все драйверы в array var cont = [controlardor1, controlador2...] и перемещать это async.series(cont, cb)

как аргумент
-1
ответ дан 24.11.2019, 15:02
  • 1
    Это почти gual что другой respueta, но это не ответ на мой вопрос. Это одинокое подает, если совсем c и # 243; я говорю, что это м и # 237; или. – Flimzy 03.01.2016, 22:20