Javascript-форум (https://javascript.ru/forum/)
-   Events/DOM/Window (https://javascript.ru/forum/events/)
-   -   Как отработает Event loop в этой ситуации? (https://javascript.ru/forum/events/64937-kak-otrabotaet-event-loop-v-ehtojj-situacii.html)

xfg 14.09.2016 22:55

Как отработает Event loop в этой ситуации?
 
Подскажите, как будет вести себя event loop. Есть такой псевдокод
const ws = new WebSocket('ws://host:port');
ws.onmessage = function (data) {
  console.log('websocket message');
}

function foo(cb) {
  setTimeout(cb);
}

foo(function () {
  setTimeout(function () {
    console.log('foo');
  });
});


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

Какой будет результат вывода на экран?

console.log('foo');
console.log('websocket message');

//или

console.log('websocket message');
console.log('foo');

Dilettante_Pro 15.09.2016 10:38

xfg,
информация к размышлению
http://javascript.ru/settimeout

xfg 15.09.2016 11:33

Я знаю, как работает settimeout. Я спрашиваю, в каком порядке коллбеки будут поставлены в очередь event loop на обработку. Я изучал, как работает javascript внутри и догадываюсь, какой будет результат, но хочу уточнить у более опытных разработчиков на javascript.

Dilettante_Pro 15.09.2016 13:25

xfg,
settimeout дает задержку для функции, включенной в него, и не имеет никакого влияния на onmessage, т.е. message придет независимо от состояния settimeout

Rise 15.09.2016 20:39

Цитата:

Сообщение от xfg
внутри функции foo по вебсокету приходит

Где в твоем псевдокоде это отражено?

xfg 15.09.2016 22:26

Rise, имеется ввиду, что уже началось исполнение функции foo интерпретатором и в этот момент по сети прилетает новое сообщение. Какой будет результат?

xfg 15.09.2016 22:34

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

То есть в stack на обработке находится

foo(cb)
main()

И в этот момент приходит сообщение. Какой будет вывод в output в результате?

Dilettante_Pro 16.09.2016 11:22

xfg,

Откройте консоль, запустите пример и быстренько кликните по окошку
Кликни!
<script>
window.onclick= function (data) {
  console.log('websocket message');
}

function foo(cb) {
  setTimeout(cb, 5000);
}

foo(function () {
  setTimeout(function () {
    console.log('foo');
  }, 5000);
});
</script>

Яростный Меч 16.09.2016 22:18

Цитата:

Сообщение от xfg (Сообщение 428813)
Dilettante_Pro, я знаю, что message придет. Вопрос был не в этом, а какой будет результат вывода на экран при условии, что в момент прихода сообщения интерпретатор уже будет выполнять функцию foo?

То есть в stack на обработке находится

foo(cb)
main()

И в этот момент приходит сообщение. Какой будет вывод в output в результате?

когда придет сообщение, в event-loop добавится задача по вызову колбэка onmessage. Эта задача дождется, когда функция foo закончит свою работу (по созданию таймера), и будет взята из очереди и выполнена, с выводом 'websocket message'.

А чуть позже, когда подойдет время таймера, он положит свою задачу в очередь, далее всё то же - взятие из очереди и выполнение.

Это на самый простой взгляд. А вообще у событий event-loop есть приоритеты, по которым, в частности, задачи от таймеров на последнем месте.

Dilettante_Pro 19.09.2016 10:22

Подробный лог последовательностей работы
Кликни!
<script>
window.onclick= function (data) {
  console.log('websocket message');
}

function foo(cb) {
  console.log('foo started');
  setTimeout(cb, 5000);
  console.log('foo ended');
}

foo(function () {
  console.log('inner started');
  setTimeout(function () {
    console.log('inner timeout ended');
  }, 5000);
  console.log('inner ended');
});
</script>

Функции отрабатывают мгновенно, клик никого не ждет


Часовой пояс GMT +3, время: 05:05.