33:45 Вот доказательство что учить других это самый лучший вид учение)) Хочу сказать что это самый лучший контент по асинхронного программировании в ноде которого я видел, тема углубленное а примеры простые и классные. Спасибо вам за то что вы делаете Тимур Гафарович!
Классный видос. Особенно спасибо за то, что объяснили, как устроен eventemitter, и за то, что показали, как можно одну и ту же функциональность написать в разных стилях
Кстати хочу заметить что скорость исполнения лямбда функции фибоначи в 6м примере на 16й ноде значительно быстрей чем то что мы видим в видео порядка 1200мс что довольно таки много как по мне -) Интересно посмотреть на нодах ниже в 14 и 18 как вариант!
5:35 await-sleep.js мы там делаем await sleep(3000) внутри асинхронной функции так вот мне интересно имеел ли смысл там ставить await в данном контексте если в слип мы и так ожидаем увидить промис? )
А EventLoop і поток виконання js кода, це два різні потоки чи один і той самий? Тобто коли стек js потока звільнився, то поток eventloop починає підкидувати в стек виконані колбеки з черги тасків, чи я щось не так зрозумів?
Добрый вечер, Тимур. Хочу разобраться с работой Event Loop, но просмотрев плейлисты не отыскал релевантного видео у вас на канале. Планируете записать такое видео? Тема интересная в том плане, что общие штуки лупа понятны и их много кто описал, а там где начинаются очереди (таски, микротаски, реквестанимейшнфрейм, рендер) уже запутано. Даже после просмотра докладов Jake Archibald, Erin Zimmer и Philip Roberts на JSConf до конца не разобрался, а на собесах спрашивают + дают мудреные задачи на эту тему
I am a little conffusing. Function g removes himself and on the next line function g call function f. How this is possible? I understand that if I deleted a function, for example, on line 10, this function doesn't exist on line 11.
Тимур, а как быть с таким моментом: при once мы удаляем из массива, а в emit мы этот массив обходим. Отсюда следует, что если мы, например, вначале вызовем once а затем например on или еще раз once, то второй обработчик НЕ ВЫЗОВЕТСЯ, т.к. при отработке первого once из массива уйдет первый элемент, а второй станет первым, соответственно forEach этот второй обработчик перескочит. Нехорошо...
Вообще на практике имхо emit всегда используется отдельно от всего остального (например в агрегатах), и его можно смело делать как emitter.eventName = () => {} через Proxy, задав ему красивый интерфейс в ts)
Здравсвуйте. В строке if(event) { event.forEach(fn => fn(...data); } как я понял, такую конструкцию надо создавать для того, чтобы в оперативной памяти ос было место, куда записывать еще и аргументы ...data. Я пробывал упростить код и не создавать массив с одним элементом [fn]. Но это не раблтает. Т.е надо создавать массив [fn], а вариант записать fn в переменную не срабатывает. Что интересно, создается обЬект (или список, что одно и тоже, как я понимаю) с ключами 'name' и значениями, представляющими массивы, но с одним элементом ([fn]). Я вот голову ломал, как обойтись без массивов, но не придумал пока...
Вот принципиальный вопрос мне не ясен по функц прогр. Здесь как раз в ивент имитере представлены разные подходы к стилю кода , хотя и там и там есть одно замыкание , но на 1:08 пример полностью переписан в функц стиле. Так вот вопрос : я так понял этот пример будет медленее будет работать ? Ну то есть как правило функц стиль ухудшает производительность ? Или это я ошибаюсь ? Или же как вариант это все незначительно ? В общем не понятно тогда как лучше писать - с перемнными или вот так вот цепочкой как на 1:08 .
Есть мнение, что писать библиотеки и подобные им инструменты лучше максимально оптимально, с переиспользованием памяти и максимальной экономией. В то время как пользовательский код может использовать ФП. Другое дело, если вы увидите, что у вас пользовательский код где-то течёт. Это место, где нужно понять, что не так и сделать его оптимальнее. "Но не слушайте меня, у меня утром шнурок порвался"
С EventEmitter вроде было понятно в начале, но как-то быстро потерялась нить событий у меня в голове, что откуда и куда ))) Как все эти связи можно удержать в памяти?
@@TimurShemsedinov В EventEmitter методы on и emit имеют переменную event, объявление которой можно избежать, при этом поведение не изменится, по крайней мере в этом примере. Особенно в методе on при первом взгляде появляется ощущение, что мы обращаемся не к объекту по ссылке, а к отдельной переменной. Например, EventEmitter.prototype.on = function(name, fn) { if (this.events[name]) { this.events[name].push(fn); } else { this.events[name] = [fn]; }
@@TheSupermaniaco В вашем примере появляется дублирование кода, два подряд обращения к this.events[name] мы получаем массив в ифе и теряем ссылку на него, потом для пуша опять получаем ссылку на массив. С переменной гораздо лучше, меньше кода дублируется.
@@TimurShemsedinov Благодарю. Тем не менее многие авторы в том числе и вы пропагандируют писать понятный код пусть и не оптимальный - зависит от задачи. Тут мы потеряем немного памяти, только в if, но интересно насколько это действительно полезно использовать переменную? Может есть пример из опыта? Я практически уверен, что человек из комментария выше запутался именно в этом месте)
Разобрался. Для тех кому тоже интересно: К примеру такой код. setTimeout(() => { console.log('Bye!'); }, 5000) const timer = setInterval(() => { console.log(process.memoryUsage()); }, 1000) Каждую секунду будет печататься memoryUsage. Это продолжится даже тогда, когда setTimeout отработает. Второй вариант: setTimeout(() => { console.log('end'); }, 5000) const timer = setInterval(() => { console.log(process.memoryUsage()); }, 1000) timer.unref(); Каждую секунду будет печататься memoryUsage. И напечатается 5 раз. Когда setTimeout отработает, приложение завершится, так как timer уже не будет требовать чтобы event loop продолжала работу. Третий вариант: setTimeout(() => { console.log('end'); }, 5000) const timer = setInterval(() => { console.log(process.memoryUsage()); }, 1000) clearInterval(timer) memoryUsage не напечатается ни разу. Скрипт завершится через 5 секунд.
unref не удаляет обработчик события, а делает так, чтобы это событие не держало процесс, т.е. если стек опустошается, то процесс выходит, не дожидаясь события. Это работает только для ноды, но не для браузера.
Слишком затянутое объяснение. Можно было гораздо короче: Лупа и Пупа пошли получать зарплату. Лупа получил за Пупу, а Пупа получил два эвентлупа. Вот и все, теперь вы готовы писать высоконагруженные распределенные системы.
я тоже люблю closure, но меня за єто не любят (( Что делать? однажди я виполнил простое тестовое. функция возвращала обьект из замикания. "Что єтим хотел сказать кандидат? Код не кроссбраузерний! Код нечитаемий!" А код продолжал упорно работать везде. Пришлось для резюмиста полдня писать комменти с обьяснениями. Но отношения били безнадежн испорчени )) Может надо жить на прототайпах...? Может наш мир - ООП?
@@romankotenko7 ну почему же, цель важна, наша цель - это безклассовое общество, построенное на базе научного метода и общественная собственность на средства производства, но парадигмы это ни в коем случае не про цель
@@TimurShemsedinov Я просмотрел несколько лекций, выбирал те, которые мне были интересны. Пока ещё не встретил 🙂. У меня не стоит цели просмотреть всё в ближайшее время, хотя они, безусловно, очень занимательные и глубоко погружают в тему. Всегда приятно, если удаётся узнать новые аспекты, казалось бы, давно знакомого материала.
@@TimurShemsedinov Всплыл ролик в рекомендациях от JSNinja про EventEmitter. Ну как я и предполагал, он сам же говорит, что это в основном используется для отладки и логирования. Иначе зачем ещё в приложение на условном socket.io запихивать EE
@@TimurShemsedinov Но здесь есть такие, которые без Ваших комментариев не могут самостоятельно при всех предложенных к рассмотрению вариантах выбрать рабочие. Мне вот именно этого в Ваишх замечательных лекциях и не хватает. Хотелось чтобы Вы больше себя добавили в материал и добавляли собственное мнение, что и когда стоит (или не стоит) использовать.
@@318307able нужно изучать все варианты, потому, что в реальных проектах код не всегда самый лучший, а как я бы писал, просто берите более сложные лекции по ноде, по архитектуре и там уже есть мои решения, но нет одного правильного на все случаи жизни, в разных случаях и я по-разному пишу
@@TimurShemsedinov Да, я понимаю. Но иногда вот этих связей с общей картиной и не хватает. Чтобы Вы объяснили когда, что и зачем использовать. Хотя этот, как мне кажется, недостаток, просто мизер с той пользой, которую Вы несете своими лекциями. Огромное спасибо!)
@@318307able каждую тему приходится 2-3 раза проходить, сначала на простом уровне, а потом усложнять, там по оглавлению курсов всегда так, если не продвинуться по другим темам, то нельзя все сразу по одной в одну лекцию запихнуть, она и длинная будет и непонятная,
0:30 callback sync/async
1:35 временная задержка sleep.js
5:35 await-sleep.js
8:40 sleep-then.js
9:30 order.js
18:38 precision.js
22:13 blocking.js
22:50 timers.js
29:35 ref-unref.js
32:05 enroll.js
34:57 eventloop.txt
37:37 eventEmitter
44:32 simple.js
47:48 usage.js
48:30 enhanced.js
50:18 star-fix.js
51:10 usage.js
53:15 closure.js
54:50 fp.js
57:10 methods.js
1:06:35 min.js
1:12:31 prod.js
33:45 Вот доказательство что учить других это самый лучший вид учение)) Хочу сказать что это самый лучший контент по асинхронного программировании в ноде которого я видел, тема углубленное а примеры простые и классные. Спасибо вам за то что вы делаете Тимур Гафарович!
Если кто зашел сюда за EventEmitter, то вам на 37:42
Классный видос. Особенно спасибо за то, что объяснили, как устроен eventemitter, и за то, что показали, как можно одну и ту же функциональность написать в разных стилях
знание - свет, автор - фонарик %)
Прекрасно!) Спасибо Тимур, как всегда на высоте!
Спасибо, довольно сложная объемная тема...
Очень интересно. Было бы шикарно добавлять тайм-коды:) Подписка и лайк)
3-enhanced.js на 49:57 "обмовка" - Array.unshift не забирає елемент із масиву, а додає його в початок.
Согласен, при чем из видео все ясно, а звук уже не исправить
Кстати хочу заметить что скорость исполнения лямбда функции фибоначи в 6м примере на 16й ноде значительно быстрей чем то что мы видим в видео порядка 1200мс что довольно таки много как по мне -) Интересно посмотреть на нодах ниже в 14 и 18 как вариант!
тут скорее от железа зависит, я наблюдаю разницу в 600мс между пк и ноутом
5:35 await-sleep.js мы там делаем await sleep(3000) внутри асинхронной функции так вот мне интересно имеел ли смысл там ставить await в данном контексте если в слип мы и так ожидаем увидить промис? )
Обязательно, await ждет когда случттся оесолв промиса, иначе исполнение пойдет дальше, без остановки
💥💥💥
А EventLoop і поток виконання js кода, це два різні потоки чи один і той самий? Тобто коли стек js потока звільнився, то поток eventloop починає підкидувати в стек виконані колбеки з черги тасків, чи я щось не так зрозумів?
58:02 Ожидал что once не будет работать, так как мы пытаемся удалить функцию g, а не f. Какая-то магия. Как indexOf ее нашёл?
Понял свою ошибку:) Невнимательность.
Добрый вечер, Тимур. Хочу разобраться с работой Event Loop, но просмотрев плейлисты не отыскал релевантного видео у вас на канале. Планируете записать такое видео? Тема интересная в том плане, что общие штуки лупа понятны и их много кто описал, а там где начинаются очереди (таски, микротаски, реквестанимейшнфрейм, рендер) уже запутано. Даже после просмотра докладов Jake Archibald, Erin Zimmer и Philip Roberts на JSConf до конца не разобрался, а на собесах спрашивают + дают мудреные задачи на эту тему
Ну вообще это есть во введении в Node.js, тут ruclips.net/video/mRvzgBGLVyM/видео.html
А тут гораздо более подробно все смежные темы ruclips.net/user/liveND5HNHicACI?feature=share
@@TimurShemsedinov спасибо, уже смотрю
Спасибо!
I am a little conffusing. Function g removes himself and on the next line function g call function f. How this is possible? I understand that if I deleted a function, for example, on line 10, this function doesn't exist on line 11.
Тимур, а как быть с таким моментом: при once мы удаляем из массива, а в emit мы этот массив обходим. Отсюда следует, что если мы, например, вначале вызовем once а затем например on или еще раз once, то второй обработчик НЕ ВЫЗОВЕТСЯ, т.к. при отработке первого once из массива уйдет первый элемент, а второй станет первым, соответственно forEach этот второй обработчик перескочит. Нехорошо...
Вообще на практике имхо emit всегда используется отдельно от всего остального (например в агрегатах), и его можно смело делать как emitter.eventName = () => {} через Proxy, задав ему красивый интерфейс в ts)
Здравсвуйте.
В строке
if(event) {
event.forEach(fn => fn(...data);
}
как я понял, такую конструкцию надо создавать для того, чтобы в оперативной памяти ос было место, куда записывать еще и аргументы ...data.
Я пробывал упростить код и не создавать массив с одним элементом [fn]. Но это не раблтает. Т.е надо создавать массив [fn], а вариант записать fn в переменную не срабатывает. Что интересно, создается обЬект (или список, что одно и тоже, как я понимаю) с ключами 'name' и значениями, представляющими массивы, но с одним элементом
([fn]).
Я вот голову ломал, как обойтись без массивов, но не придумал пока...
Вот принципиальный вопрос мне не ясен по функц прогр. Здесь как раз в ивент имитере представлены разные подходы к стилю кода , хотя и там и там есть одно замыкание , но на 1:08 пример полностью переписан в функц стиле. Так вот вопрос : я так понял этот пример будет медленее будет работать ? Ну то есть как правило функц стиль ухудшает производительность ? Или это я ошибаюсь ? Или же как вариант это все незначительно ? В общем не понятно тогда как лучше писать - с перемнными или вот так вот цепочкой как на 1:08 .
Есть мнение, что писать библиотеки и подобные им инструменты лучше максимально оптимально, с переиспользованием памяти и максимальной экономией. В то время как пользовательский код может использовать ФП.
Другое дело, если вы увидите, что у вас пользовательский код где-то течёт. Это место, где нужно понять, что не так и сделать его оптимальнее.
"Но не слушайте меня, у меня утром шнурок порвался"
С EventEmitter вроде было понятно в начале, но как-то быстро потерялась нить событий у меня в голове, что откуда и куда )))
Как все эти связи можно удержать в памяти?
25 лет тренировки
@@TimurShemsedinov В EventEmitter методы on и emit имеют переменную event, объявление которой можно избежать, при этом поведение не изменится, по крайней мере в этом примере. Особенно в методе on при первом взгляде появляется ощущение, что мы обращаемся не к объекту по ссылке, а к отдельной переменной. Например,
EventEmitter.prototype.on = function(name, fn) {
if (this.events[name]) {
this.events[name].push(fn);
} else {
this.events[name] = [fn];
}
@@TheSupermaniaco В вашем примере появляется дублирование кода, два подряд обращения к this.events[name] мы получаем массив в ифе и теряем ссылку на него, потом для пуша опять получаем ссылку на массив. С переменной гораздо лучше, меньше кода дублируется.
@@TimurShemsedinov Благодарю. Тем не менее многие авторы в том числе и вы пропагандируют писать понятный код пусть и не оптимальный - зависит от задачи. Тут мы потеряем немного памяти, только в if, но интересно насколько это действительно полезно использовать переменную? Может есть пример из опыта?
Я практически уверен, что человек из комментария выше запутался именно в этом месте)
@@TheSupermaniaco память выделяется под значение переменные бесплатные
в чем разница между timer.unref() и clearTimeout(timer) ?
Разобрался.
Для тех кому тоже интересно:
К примеру такой код.
setTimeout(() => {
console.log('Bye!');
}, 5000)
const timer = setInterval(() => {
console.log(process.memoryUsage());
}, 1000)
Каждую секунду будет печататься memoryUsage. Это продолжится даже тогда, когда setTimeout отработает.
Второй вариант:
setTimeout(() => {
console.log('end');
}, 5000)
const timer = setInterval(() => {
console.log(process.memoryUsage());
}, 1000)
timer.unref();
Каждую секунду будет печататься memoryUsage. И напечатается 5 раз. Когда setTimeout отработает, приложение завершится, так как timer уже не будет требовать чтобы event loop продолжала работу.
Третий вариант:
setTimeout(() => {
console.log('end');
}, 5000)
const timer = setInterval(() => {
console.log(process.memoryUsage());
}, 1000)
clearInterval(timer)
memoryUsage не напечатается ни разу. Скрипт завершится через 5 секунд.
unref не удаляет обработчик события, а делает так, чтобы это событие не держало процесс, т.е. если стек опустошается, то процесс выходит, не дожидаясь события. Это работает только для ноды, но не для браузера.
@@TimurShemsedinov спасибо, Тимур! Уложилось в голове.
Слишком затянутое объяснение. Можно было гораздо короче: Лупа и Пупа пошли получать зарплату. Лупа получил за Пупу, а Пупа получил два эвентлупа. Вот и все, теперь вы готовы писать высоконагруженные распределенные системы.
Пусть лучше Пу получит за Лупу .
Тайминг EventEmitter - ruclips.net/video/LK2jveAnRNg/видео.html
А можно ссылки на репозиторий где можно склонить код?
В описании к видео
я тоже люблю closure, но меня за єто не любят (( Что делать?
однажди я виполнил простое тестовое. функция возвращала обьект из замикания. "Что єтим хотел сказать кандидат? Код не кроссбраузерний! Код нечитаемий!" А код продолжал упорно работать везде. Пришлось для резюмиста полдня писать комменти с обьяснениями. Но отношения били безнадежн испорчени )) Может надо жить на прототайпах...? Может наш мир - ООП?
Наш мир мультипарадигменный, живем на смешении всего и парадигмы для нас - это способ строить абстракции и делать понятный и удобный синтаксис
@@TimurShemsedinov Забей на цель, живи реализацией! ))
@@romankotenko7 ну почему же, цель важна, наша цель - это безклассовое общество, построенное на базе научного метода и общественная собственность на средства производства, но парадигмы это ни в коем случае не про цель
@@TimurShemsedinov Ким Чен Ын, к доске, тяните билет.
@@TimurShemsedinov вот за этот комментарий респектище последний ваш) но надо за эту идею нам всем бороться
Хорошо бы привести более-менее реальные случаи, когда использование EventEmitter оправдано.
Во многих последующих лекциях, особенно по node.js он пртменяется. Смотрите дальше
@@TimurShemsedinov Я просмотрел несколько лекций, выбирал те, которые мне были интересны. Пока ещё не встретил 🙂. У меня не стоит цели просмотреть всё в ближайшее время, хотя они, безусловно, очень занимательные и глубоко погружают в тему. Всегда приятно, если удаётся узнать новые аспекты, казалось бы, давно знакомого материала.
@@TimurShemsedinov Всплыл ролик в рекомендациях от JSNinja про EventEmitter. Ну как я и предполагал, он сам же говорит, что это в основном используется для отладки и логирования.
Иначе зачем ещё в приложение на условном socket.io запихивать EE
@@AlbertMaximov socket.io это устаревшая ересь и пучок говнокода
@@AlbertMaximov пример ruclips.net/video/RbhYxygxroc/видео.html
Пример 9 - имхо, как НЕЛЬЗЯ писать код. Можно было еще через обфускатор пропустить :)
Конечно нельзя, это все, чтоб люди српвнили подходы)
@@TimurShemsedinov Но здесь есть такие, которые без Ваших комментариев не могут самостоятельно при всех предложенных к рассмотрению вариантах выбрать рабочие. Мне вот именно этого в Ваишх замечательных лекциях и не хватает. Хотелось чтобы Вы больше себя добавили в материал и добавляли собственное мнение, что и когда стоит (или не стоит) использовать.
@@318307able нужно изучать все варианты, потому, что в реальных проектах код не всегда самый лучший, а как я бы писал, просто берите более сложные лекции по ноде, по архитектуре и там уже есть мои решения, но нет одного правильного на все случаи жизни, в разных случаях и я по-разному пишу
@@TimurShemsedinov Да, я понимаю. Но иногда вот этих связей с общей картиной и не хватает. Чтобы Вы объяснили когда, что и зачем использовать.
Хотя этот, как мне кажется, недостаток, просто мизер с той пользой, которую Вы несете своими лекциями. Огромное спасибо!)
@@318307able каждую тему приходится 2-3 раза проходить, сначала на простом уровне, а потом усложнять, там по оглавлению курсов всегда так, если не продвинуться по другим темам, то нельзя все сразу по одной в одну лекцию запихнуть, она и длинная будет и непонятная,
как же туго ты всё объясняешь...
может ты тугой?)
@@spir1tfly чувак подписан на "WebDev с нуля. Канал Алекса Лущенко", тут всё ясно, странно что нету подписки на хауди хо)