Существуют ли какие-либо события или обратные вызовы DOM / Browser API, которые являются немедленными (прерывая текущий поток) - PullRequest
0 голосов
/ 02 июля 2018

Большинство обратных вызовов и событий JavaScript / HTML / DOM / Browser не являются немедленными или не повторными (не уверен, что это правильное слово здесь). Я имею в виду, что даже если событие приходит, оно добавляется в очередь в браузере и не обрабатывается, пока не завершится текущее событие.

В качестве примера, если я пытаюсь загрузить изображение

 const img = new Image();
 img.onload = function() {
   console.log("image loaded");
 }
 img.src = 'https://i.imgur.com/ZKMnXce.png';
 for (let i = 0; i < 100000; ++i) {
   console.log(i);
 }

При условии, что браузер не превысил время ожидания, цикл for, указанный выше, гарантированно будет запущен до доставки события onload.

Другим примером может быть postMessage

 window.onmessage = function() {
    console.log('got message');
 }
 window.postMessage({}, '*');
 for (let i = 0; i < 100000; ++i) {
   console.log(i);
 }
 

Снова цикл завершится до того, как придет событие сообщения.

Эти 2 являются событиями, но, конечно, есть такие функции, как setTimeout и requestAnimationFrame, которые принимают обратный вызов.

requestAnimationFrame(function() {
  console.log('requestAnimationFrame');
});
setTimeout(function() {
  console.log('setTimeout');
}, 0);
for (let i = 0; i < 100000; ++i) {
  console.log(i);
}

Снова цикл завершится до того, как будут вызваны обратные вызовы rAF или setTimeout.

Теперь, конечно, можно вручную написать API, которые принимают обратные вызовы, которые вызывают немедленно. На самом деле AFAICT это распространенная ошибка и считается анти-паттерном. Пример

 /*
  * @param {*} params The params
  * @param {function(error, result)} callback where first param is error, null on success
  */
 function doSomethingAsyncThenCallback(params, callback) {
    if (params are bad) {
      callback("bad params");
      return;
    }
    dSomethingAsync then callback(null, result)
 }

AFAIK, который считается плохим шаблоном, поскольку пользователь может не ожидать обратного вызова до тех пор, пока не завершится его текущее событие. Рекомендуемый способ написать что-то подобное:

 /*
  * @param {*} params The params
  * @param {function(error, result)} callback where first param is error
  */
 function someSomethingAsyncThenCallback(params, callback) {
    if (params are bad) {
      setTimeout(() => { callback("bad params"); }, 0);
      return;
    }
    do something async then callback(null, result)
 }

Так что независимо от кода пользователя обратный вызов поступит после окончания текущего события.

Итак, мой вопрос: существуют ли какие-либо API-интерфейсы браузера (как в API, встроенных в браузер, такие как XHR, canvas 2d, WebGL, WebAudio, шифрование, геймпад, websocket, webrtc, localstorage и т. Д.), Куда могут поступать обратные вызовы / события непосредственно перед выходом из текущего события?

Я знаю, что JavaScript не может быть прерван. Но, как и в случае с плохо реализованным JS API выше, при успешном завершении будет ожидать выхода из текущего события, а при неудачном вызове обратный вызов будет немедленно, есть ли у их собственных API-интерфейсов браузера такое поведение?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...