Наше приложение мы успешно сверстали. Но оно пока не делает ничего интересного. Исправим это.
Сделаем нашу статическую страницу динамической. Добавим таймер для виджета часов. Сделаем отложенную загрузку лотов по API. Реализуем обновление цен в реальном времени по примеру работы с WebSocket-уведомлениями.
Рассмотрим проблемы классического подхода прямого изменения DOM-элементов и перейдём на иммутабельные компоненты. Уберём лишние зависимости и переведём фронтенд на однонаправленный поток управления.
Дальше займёмся решением проблем производительности и реализацией настоящей реактивности.
Чтобы не пропускать новые эпизоды подпишитесь на наш канал @deworkerpro в Telegram
Спасибо, Дмитрий! Первый раз, первым оставил след )
Очень понравился скрин каст. Классно, что теперь и по джс идет изложение в стиле Дмитрия. Надеюсь, что и про тайп скрипт когда-то пару слов скажете. Спасибо.
Спасибо, за урок! Да, весьма интересный вопрос, только тайп скрипт может дать соблюдение строгости написания кода и крутые подсказки в шторме, но с другой стороны, возрастет сложность проекта и восприятие кода будет малость усложнено, тоже интересно по какому пути пойдет Дмитрий.
Да, про TypeScript скажу.
Спасибо.
Спасибо! Очень нравятся ваши уроки!
21:08 я давно в JS не заглядывал. Синтаксический сахар синтаксического сахара. Комбо-вомбо :)
Дмитрий, спасибо, очень своевременно! Меня уже начал немного бесить фронтенд, но теперь я вижу и в нём логичные приёмы!
Вопрос не по теме урока, но не нашёл куда: доработайте пожалуйста сайт чтобы он запоминал какие видео я посмотрел а какие нет. Захожу не так часто - много времени уходит понять что я смотрел а что нет. Учитывая что я ещё часто не по порядку смотрю а только интересные темы.
Добавил в планы по доработке. Спасибо!
Суперское объяснение 👍 Спасибо за то, что Вы делаете!
Я не думал что в этом плеере можно ускорить воспроизведение. Гораздо понятнее когда x2 )
айкон))
Пожалуйста, прикладывайте исходный файл каждого урока - чтобы можно было разобраться в процессе, попрактиковать.
Пробовал переписывать - но это отнимает уйму времени, и крайне неудобно.
Спасибо!
P.S. В рамках данной серии уроков JSFiddle, думаю, будет предостаточно
Частично решено: в коммитах проекта на Github есть изменения :)
А можете, пожалуйста, скинуть ссылочку на проект на Github?
В конце урока есть "Исходный код на GitHub" при наличии подписки Deworker есть. Боюсь, если продублирую - нарушу правила.
В Репозитории есть "105 commits"(комбинация CTRL+F в Firefox для поиска по тексту) - там есть исходный код уроков и шагов в них.
Унификация рендеринга - очень красиво.
Вы убрали прямое упоминания Виджета. Просто остался "сигнал" о изменении и вызов тонкого метода ререндеринга.
Ничего лишнего, всё просто и читаемо. Восхитительно!
Дмитрий, помогите разобраться с принципом действия Промисов, молю!
Представим поток выполнения:
В шаге #2 Promise разблокировал поток вынеся загрузку "в фон" (WebAPI), дав возможность выполнятся шагу #3 в процессе загрузки изображения. А результат выполнения loadPicture поместит, когда загрузка будет выполнена (и стек свободный).
Верно? Это чисто для этого Промисы используются?
Просто в JS код выполняется не один раз. У JS-движка есть так называемый Event Loop. Это бесконечный цикл, запускающих выполнение кода из очереди итерациями (тиками):
Простой синхронный скрипт выполняется весь в первом тике и очередь опустошается.
Но из нашего скрипта мы можем закинуть туда в очередь на будущее (как будто в фон) любой свой коллбэк через
process.nextTick
:и он выполнится в следующей итерации. Туда же в очередь закидываются все события из окна браузера вроде наших кликов.
Например, туда мы можем поместить проверку готовности чего-нибудь. И если готово, то выполнить
onSuccess
. А если ещё нет, то повторно подписаться на следующий тик:В итоге у нас выведется
Started
, аcheck
просто закинет коллбэк в очередь для следующей итерации Event Loop. И когда-нибудь потом в одной из итераций сработаетif
, вызоветсяonSuccess
и выведетсяReady
.И так закидывая некоторые фрагменты кода в
nextTick
можно делать код, в котором выполнение фрагментов будет чередоваться. Это и есть асинхронность. Примерно так и работают все асинхронные операции. Они просто вбрасывают свой код с коллбэком в следующий тик. И когда-нибудь в каком-нибудь тике этот код переданный коллбэк вызовет.А промис - это просто объект-контейнер, в котором хранятся наши три функции и статус c результатом. В конструктор передаётся наш основной код
executor
с любым асинхронным кодом, а потом вthen
иcatch
передаются коллбэки, которые он вызовет потом в случае успеха или ошибки.И если бы мы сами писали
Promise
, то в более простом виде могли написать его с приёмом всех трёх функций в конструктор:И использовали бы его как:
И это бы вывело результат как с настоящим промисом:
Мы у себя в промисе поместили вызов
onSuccess
вnextTick
. Но реальный Event Loop сложнее и этапов там несколько. В нативном промисе в JS коллбэки изthen
иcatch
выполняются не в следующем тике, а на этапе микрозадач после текущего тика.Таким образом промис - это обёртка, помогающая записывать асинхронный код с коллбэками в более удобном виде.
А в вашем примере не сам промис разблокирует поток, а просто его не блокирует асинхронная функция
loadPicture
. В каком-то тике она увидит, что файл до конца догружен и вызоветresolve
, который дёрнетdisplayPicture
. Если жеloadPicture
будет синхронной, то она выполнится сразу и промис ей никак не поможет.Уточню: Сама асинхронная функция выполняется в "Отдельном потоке" (фон).
Event Loop следит - закончила ли выполнение асинхронная функция?
И если да - помещает её результат в Стак "Основного Потока".
Нарисовал иллюстрацию (порядок действий - пронумерован цифрами)
Обязанность Event Loop - следить закончила ли выполнение асинхрон. функция, и помещать её результат (коллбек) в Основной поток?
(И большое спасибо за подробное объяснение)
Только при многопоточности код выполняется одновременно параллельно в "фоне" в других потоках.
А при асинхронности весь код выполняется последовательно в одном потоке чередуясь. В нём задача отправляется не в отдельный поток-фон, а просто добавляется в массив-очередь, чтобы Loop его запустил в этом же потоке после того, как завершится предыдущий код.
В дополнение, иллюстрация работы Event Loop'a
Или войти через: