Андрей Кобец

Канал для Frontend разработчиков и посвящен промышленной разработке, работе в Бигтехах, фундаментальным основам программирования, Computer Science.

Обо мне:
 
20 лет в коммерческой разработке
13 лет на позиции Senior разработчика
10 лет в Яндексе
Основатель школы продвинутого программирования Kobezzza.Lab (с 2021 г.)
Автор собственного языка программирования и множества открытых библиотек


Андрей Кобец

🥳 После 1.5 месяцев непрерывной разработки (рекорд получается) я с радостью готов представить мой новый турбо-курс - IndexedDB в действии (kobezzza.ru/indexeddb) 🔥

По началу может показаться странным, что я потратил так много времени на разработку и общая длительность получившегося материала ~8 часов.

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

Да и сам IndexedDB на мой взгляд один из самых недооцененных инструментов в Web.

* Во-первых, он с нами уже 100 лет в обед (только задумайтесь, IndexedDB появился раньше Promise) и он прекрасно поддерживается во всех браузерах.

* Во-вторых, он реализует документ-ориентированную модель хранения данных и позволяет бесшовно сохранять в базе почти все стандартные JS объекты, а затем также бесшовно их считывать.

* В третьих, он позволяет хранить гигабайты информации (в том числе бинарной), что выглядит особенно внушительно против 5МБ у LocalStorage. Более того, IndexedDB использует индексы, чтобы не держать в памяти все данные сразу, а также осуществлять более сложные запросы.

* В четвертых, IndexedDB изначально спроектирован на поддержку работы из нескольких потоков. Механизмы транзакций позволят вам гарантированно защитится от гонок данных.

* А самое главное, что использовать его почти также просто как LocalStorage и, на мой взгляд, в половине случаев, когда мы используем LocalStorage, нам удобнее будет работать с IndexedDB.

Но при всех этих безусловных плюсах инструмент старательно избегается большинством разработчиков. Вместо этого они либо грузят сотни килобайт библиотек, которые "как будто бы проще" (спойлер, это не так) и они под капотом все равно используют IndexedDB. Либо всегда используют LocalStorage и обмазываются костылями, для обхода всех ограничений.

Я постарался сделать курс таким, чтобы не только рассказать про существующий API, но и объяснить почему он именно такой. На протяжение 8 часов курса мы будем вновь и вновь задавать вопросы, а затем находить ответы.

При этом пусть цифра 8 часов не пугает вас, ведь курс поделен на лекции, где постепенно, шаг за шагом, мы погружаемся в разбор этого могущественного API и связанного с ним. Кроме того, помимо ванильного API в курсе разбираются наиболее популярные библиотеки использующие IndexedDB: idb, idb-keyval, LocalForage, Dexie.js, PouchDB.

Не обошёл стороной я и тему с архитектурой Local First: в курсе разбираются сразу два возможных решения для синхронизации данных (Dexie Cloud и CouchDB/PouchDB). Причем PouchDB посвящена отдельная лекция, где мы разбираем стратегии разрешения конфликтов, распределенные индексы, Map/Reduce и многое другое!

При этом курс доступен в двух вариантах: только IndexedDB и с дополнительными лекциями по библиотекам и Local First.

На сайте турбо-курса можно детальнее ознакомится с тарифами, программным планом и посмотреть кусочек первой лекции.

kobezzza.ru/indexeddb

9 months ago | [YT] | 3

Андрей Кобец

Привет! Одной из концепций из мира ФП, которая по началу взорвала мой мозг🤯, была модель вычисления вызова функции.

Например,

function get(a, b) { if (a != 0) return a; else return b; }
get(1, undefined());

Думаю каждому из нас очевидно, что данный код выбросит исключение, т.к. вторым аргументом функции get мы передаем вызов другой функции.

Но той, другой функции не существует. Более того, чтобы подчеркнуть это, я попытался вызывать как функцию undefined, что естественно невозможно.
Но что если я скажу, что точно такой же код без проблем будет работать в Haskell?🤩

ghci

get a b = if (a /= 0); then a; else b;
-- В Haskell для вызова функций не нужно ставить круглые скобки
get 1 undefined

Как же это работает?

Все дело в том, что в большинстве языков, с которыми мы работает стратегия вычисления функций устроена таким образом,
что сначала должны быть вычислены все аргументы, а потом уже происходит вызов функции.

Такую стратегию можно назвать "энергичной". А в Haskell работает иная стратегия, которую можно назвать "ленивой".

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

Но в нашем примере получается так, что пока выполняется условие (a != 0), то нет обращений ко второму аргументу, поэтому и нет ошибки.

get a b = if (a /= 0); then a; else b;
-- Увидим ошибку
get 0 undefined

Такая вот ленивая стратегия вычисления функций имеет очень интересные последствия, но сейчас я не хочу уходить в дебри ФП и Haskell,
а показать, что мы можем легко сделать тоже самое в привычном нам мире - давайте просто "заворачивать" аргументы в функциональный контейнер.

function get(a, b) { if (a() != 0) return a(); else return b(); }
get(() => 1, () => undefined());

💡Работает! Мы просто передаем аргументы как функции, а уже их вычисление происходит "внутри" нашей главной функции.
Но, разумеется тут есть нюанс, что вычисление аргументов будут делаться "каждый раз".
Например, if (a() != 0) return a(); вот здесь значение *a* вычисляется дважды.

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

Решение, на самом деле, на поверхности - нам просто нужно сделать функциональный контейнер с поддержкой мемоизации.
Давайте сделаем это.

function lazy(constr) {
let value;
let state = 0;

return function lazyContainer() {
if (state === 0) {
value = constr();
state = 1;
}

return value;
};
}

function get(a, b) { if (a() !== 0) return a(); else return b(); }
get(lazy(() => 1), lazy(() => undefined()));

Теперь вычисления значения аргумента будет делать ровно один раз при первом обращении.
Использование таких вот ленивых контейнеров может помочь оптимизировать выделение ресурсов в тех случаях, когда некоторые данные нам нужны не сразу и могут вообще не понадобиться.
А также, позволить нам выстраивать более богатые абстракции.😊

✅Если тема контейнерных типов и ФП интересна тебе, то приглашаю на новый поток моего авторского курса "CS во Frontend", где мы детально разбираем множество важнейших примитивов из мира ФП. А, помимо этого, изучаем фундаментальные структуры данных и алгоритмы, учимся работать с бинарными данными, изучаем паттерны проектирования и многое другое.

kobezzzaweb.com/

Начни меняться, стань инженером. 🧑‍🔧👩‍🔧

И да пребудет с тобой база!✊🏻

1 year ago | [YT] | 2

Андрей Кобец

Друзья! Приглашаю вас завтра 6 ноября в 12:00 по Мск на прямой эфир. Поговорим про будущее IT, искусственный интеллект и роль человека. До встречи!

3 years ago | [YT] | 0