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

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>

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

warren buffet 19.09.2016 14:16

Цитата:

Сообщение от Dilettante_Pro
лог

Не смеши мои тапочки. Консоль сам работает асинхронно, тайминг через нее проверить невозможно. Это надо в массив писать, а потом выводить его с метками времени.

Dilettante_Pro 20.09.2016 10:50

warren buffet,
Ви делаете мне приятно, шо у ваших тапочек хорошее настроение с моего поста.
Ну а по делу, по сути темы? Что-то в принципе не так?
Ну таки вот вам лог с временем
Кликни!
<script>
var start = new Date
      log   = [];
window.onclick= function (data) {
  log.push('websocket message ' + (new Date - start));
}

function foo(cb) {
  log.push('foo started ' + (new Date - start));
  setTimeout(cb, 5000);
  log.push('foo ended ' + (new Date - start));
}

foo(function () {
  log.push('inner started ' + (new Date - start));
  setTimeout(function () {
    log.push('inner timeout ended ' + (new Date - start));
    console.log(log);
  }, 5000);
  log.push('inner ended ' + (new Date - start));
});
</script>

И что? и где? и когда?

warren buffet 20.09.2016 12:05

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

Dilettante_Pro 20.09.2016 12:33

warren buffet,
Хотелось бы увидеть ваш вариант хронометража этого процесса

warren buffet 20.09.2016 13:40

А какая модель?

Dilettante_Pro 20.09.2016 14:27

Цитата:

Сообщение от warren buffet (Сообщение 429212)
А какая модель?

прочтите тему и соорудите

warren buffet 21.09.2016 22:30

Я не умею из кодов делать ТЗ. Это рони умеет.

xfg 22.09.2016 08:15

Яростный Меч, таймеры для примера (упрощения), вместо них будут асинхронные задачи. При моем условии, очередь задач будет такой:

1. function (data) {
console.log('websocket message');
}
2. setTimeout(cb)
3. setTimeout(function () {
console.log('foo');
});

И вывод такой

Цитата:

console.log('websocket message');
console.log('foo');
Всё верно? или нет?

warren buffet 22.09.2016 08:36

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

xfg 23.09.2016 00:14

warren buffet, я хочу просто понять, как отработает event loop в этой ситуации и всё. Если вы знаете, в каком порядке будут выведены сообщения, напишите. Я задал конкретный вопрос и хочу конкретный ответ. Если не понимаете, что я хочу, уточните, попытаюсь описать подробнее. Но отвечающему нужно знать, как работает event loop в javascript, чтобы вы не тратили мое время, а я ваше.

Dilettante_Pro 23.09.2016 16:25

xfg,
Вариант лога хронометража из примера в пост 12
0:"foo started 0"
1:"foo ended 0"

2:"websocket message 2107"
3:"websocket message 2355"
4:"websocket message 2618"
5:"websocket message 2899"
6:"websocket message 3514"
7:"websocket message 3786"
8:"websocket message 4338"
9:"websocket message 4578"
10:"inner started 5001"
11:"inner ended 5001"

12:"websocket message 5434"
13:"websocket message 5674"
14:"websocket message 7050"
15:"websocket message 8155"
16:"websocket message 8330"
17:"websocket message 9138"
18:"inner timeout ended 10001"
19:"websocket message 10218"
20:"websocket message 10467"


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