Цифровий феодалізм. Чи може ШІ скасувати «нове кріпацтво»?
Гаспар Кеніг – французький письменник і філософ, засновник руху Simple, який виступає за радикальне спрощення бюрократичного апарату держави. Працюючи над книгою «Кінець індивідуума», він зустрівся з десятками фахівців у галузі штучного інтелекту , щоб дізнатися, які реальні можливості та виклики несуть революційні технології, як вони змінять звичну економіку, політику та наше повсякденне життя. З дозволу видавництва Individuum публікуємо уривок із розділу «На захист права володіння персональними даними».
У Нью-Йорку я зустрівся з Алексом Еліасом, засновником стартапу Qloo. Він ставить перед собою завдання схрестити індивідуальні переваги в різних областях: якщо вам подобається така музика або такий фільм, ви повинні спробувати такий ресторан або піти на побачення з такою людиною … Qloo міг би стати Netflix для життя, що занурює своїх користувачів у тотальні рекомендації, від яких ніщо не вислизає. У цьому сенсі прагнення до «культурної персоналізації» є саме тим, що лякає мене в ШІ. Але Алекс — інтелектуал зі Східного узбережжя, аматор джазу, який розуміється на перевагах імпровізації. Він знає, що похід у магазин платівок відкриває перед ним несподівані перспективи, тоді як Spotify дає лише обмежений досвід. Проаналізувавши пошук у Qloo, він констатує, що більшість американців вказує як улюблену книгу Біблію, а як улюблений фільм — останній блокбастер… Залишені на милість алгоритму, що оптимізує, вони, ймовірно, підуть найтрадиційнішим шляхом. Ось чому Алекс включив у програму Qloo те, що він називає “фактором диверсифікації”. З одного боку, елемент випадковості вводиться в систему рекомендацій, щоб влаштовувати сюрпризи та викликати питання. З іншого боку, користувач контролює деяку кількість критеріїв: це щоб влаштовувати сюрпризи та викликати питання. З іншого боку, користувач контролює деяку кількість критеріїв: це щоб влаштовувати сюрпризи та викликати питання. З іншого боку, користувач контролює деяку кількість критеріїв: це «перша директива» в дії! Щоб пробудити свідомість, що задрімала, потрібна випадковість, а щоб переорієнтувати алгоритм — наявність чітко вираженого вибору.
Алекс визнає, що надана індивіду влада над власними уподобаннями, як не дивно, робить Qloo менш ефективним і тому менш прибутковим. Зрештою, лаконічно зауважує він, «більшість людей хоче розчинитися в масі». Але він хоча пропонує їм альтернативу, втішаючи себе думкою про те, що нові покоління будуть чутливішими до різноманітності. Крім того, потрібно розраховувати на вільний ринок алгоритмів, щоб викликати до життя проекти, більш уважні до вільного володаря, і сподіватися, що вони поступово завоюють користувачів, залучених перспективою звільнення. А поки що кожен може спробувати перехитрити машину. Наприклад, користуючись Google Map, я завжди відключаю геолокацію: отримуючи користь із розрахунку відстаней, я хочу сам визначати вулиці, щоб розуміти, куди їду, а не сліпо слідувати за синьою кулькою. У Deezer я намагаюся вибирати композиції зі списку, критерії якого встановив сам (наприклад, «сонати»), не покладаючись на рекомендації. Я сам наголошую на дні народження своїх (справжніх) друзів у щоденнику і не чекаю, поки мені нагадає про них LinkedIn. А ще я йду з ютуба, коли закінчується відео, яке я вибрав, хоча зробити це непросто — адже так легко і приємно віддаватися потоку образів.
Але всі ці хитрощі смішні, тому що ринок підтасований. Оскільки платформи мають практично вільний доступ до наших персональних даних, все наше цифрове життя ми займаємося тим, що живимо різні ШІ, які у відповідь нами маніпулюють. Nudge усюди, він не залишає жодної можливості для виваженого та самостійного рішення, з’являючись у формі реклами, повідомлень, рекомендацій, повідомлень у соціальних мережах чи спаму у поштових скриньках. Наш мозок постійно піддається хакінгу, який став можливим завдяки тому, що ми скрізь розкидаємо свої дані. Відкрити інтернет — це як опинитися без штанів у публічному місці, подібно до короля з казки Андерсена: він вважав, що на ньому вбрання з дорогоцінної тканини, а насправді було зовсім голим. У цьому може справді переконатися кожен. Браузер, розроблений стартапом myCo, наприклад, дозволяє візуалізувати всіх чужинців, присутніх на сайті, збирає куки та ін. щоб краще інтерпретувати та спрямовувати мою поведінку. Це пограбування абсолютно законне: протягом дня кілька разів ставлячи галочку «Я згоден» у користувацьких угодах, ми добровільно йдемо на те, щоб бути під ковпаком біля платформ. Хитростям, які сайти та програми використовують для того, щоб збирати наші дані, немає числа. Так, програма, що включає ліхтарик на вашому смартфоні, в обмін на цю крихітну послугу забирає всі ваші дані з геолокації. Пам’ятаю, як сидів у ресторані в Парижі навпроти підприємця, який з гордістю оголосив про свій новий «інноваційний проект» — стежити за пересуваннями миші екраном, щоб відточити профіль користувачів. На моє запитання, чи не надто нав’язливий характер носить ця технологія, він знизав плечима і відповів, що вона послужила б хорошу службу всім нам, після чого почав обговорювати зі своїм сусідом по столу проблеми благодійності. Тартюфи 2.0 явно заслуговують на нову п’єсу…
Ну і як тоді «цифрові» громадяни можуть ретельно відбирати алгоритми, якщо кожним своїм кліком, кожним відкриттям програми вони дають ШІ зброю проти себе? Якщо нам не вдасться тримати наші дані при собі, ми потрапимо під владу могутніх ШІ, які унеможливлять будь-який вільний вибір, а отже, і появу будь-яких альтернатив. Європейський загальний регламент захисту даних (GDPR) спробував було ввести свого роду контроль, вимагаючи більшої прозорості від інтернет-компаній. Однак у результаті нам ще частіше доводиться кликати на «Я згоден», але при цьому ми так і не отримали жодної реальної можливості заперечувати умови чи вести переговори.
[…]
Якщо ми хочемо зрозуміти, як влаштовано цифрове пограбування, жертвами якого ми сьогодні стали, достатньо почитати роботи Жоржа Дюбі про економіку Середньовіччя. На початку попереднього тисячоліття кріпаки, прив’язані до землі, віддавали феодалу основну частину плодів своєї праці в обмін на «безкоштовні послуги», більш-менш реальні: захист під час війни або користування сільською інфраструктурою, що належить феодалу (піччю, млином, давильним пресом). Потрібно було дуже багато часу, щоб селяни поступово отримали право передавати майно у спадок, вільно торгувати плодами своєї праці і, нарешті, відчужувати їх за наявності документів про право власності, яке може перепоступатися. Велика французька революція поклала край феодальної ленной системі і розширила декларація про володіння землею: кріпак став вільною людиною. За кожної технічної інновації спалахують схожі дебати. Через кілька століть після винаходи друкарства Бомарше очолив боротьбу письменників за визнання авторських прав. Під час промислової революції винахідники досягли створення справжнього патентного режиму. Людина завжди повинна боротися за право вільно розпоряджатися своєю власністю та плодами своєї творчості, будь вони матеріальними чи інтелектуальними.
Сьогодні ми стали цифровими кріпаками, передавши право на збирання всіх наших даних в обмін на безкоштовні послуги (цінність яких не завжди однозначна), що надаються нашими новими феодалами. Ми постимо по мільярду фотографій у фейсбук щодня. Саме так по мільярду. Після обробки алгоритмами, в які інтегровано розпізнавання осіб, ця скарбниця даних приносить щоквартальний прибуток близько кількох мільярдів доларів. Який відсоток від неї потрапляє до вихідного виробника? Ніякий. Ну хіба що чайові у вигляді мережі друзів… Ми не тільки не можемо вести переговори з нашим феодалом щодо даних, нам заборонено навіть продавати їх на ринку: у травні 2018 року Олі Фрост, заповзятливий британський мілініал, який виставив на eBay свої посади у фейсбуці десять років, був змушений зняти свою пропозицію як таке, що порушує умови користування соціальною мережею. Однак перебіг міркувань Олі Фроста здавався надзвичайно переконливим: «Оскільки всі заробляють гроші на моїх персональних даних, чому б мені не заробляти їх самому?» Ставки на аукціоні сягнули 400 доларів, але феодал явно було змиритися з подібним порушенням його прерогатив. Воно й зрозуміло: за даними Європейської комісії, вартість персональних даних у 2020 році наблизилася до трильйона євро, тобто до 8% ВВП Європейського Союзу. Хто ж захоче ділитися цією небесною манною зі збродом, який її виробляє? але феодал явно було змиритися з подібним порушенням його прерогатив. Воно й зрозуміло: за даними Європейської комісії, вартість персональних даних у 2020 році наблизилася до трильйона євро, тобто до 8% ВВП Європейського Союзу. Хто ж захоче ділитися цією небесною манною зі збродом, який її виробляє? але феодал явно було змиритися з подібним порушенням його прерогатив. Воно й зрозуміло: за даними Європейської комісії, вартість персональних даних у 2020 році наблизилася до трильйона євро, тобто до 8% ВВП Європейського Союзу. Хто ж захоче ділитися цією небесною манною зі збродом, який її виробляє?
Дивно, наскільки пасивно ми приймаємо цей цифровий феодалізм… Ймовірно, кріпаки XII століття навіть не мріяли про те, щоб оскаржувати права сеньйора, що лежить під своїм балдахіном, — фігури так само священної, що й сьогоднішній підприємець із технологічного сектору на сцені TED Talk. Але оскільки все прискорюється, революція може статися швидше. Право власності на персональні дані, що поки що не існує ніде у світі, поклало б край цьому пограбуванню. Воно включало б виробника даних у ланцюжок виробництва вартості в цифровій економіці, дозволяючи йому монетизувати (або не монетизувати) свої дані згідно з умовами договору, які він обере і які посередники від його імені обговорюватимуть із платформами. Питання про винагороду видається мені другорядним. Важливіше інше: згідно із законом повернувши собі власність на свої дані, людина з новою силою відчує, що вона існує, як селянин, який відчуває задоволення від того, що обробляє «свою» землю. Він має право не вирощувати на ній нічого, крім ожини, будяка і терну, або, у разі даних, має право відмовитися від їх надання, не віддаючи їх в обробку ШІ. Кожен зможе вибирати, що він приховує і на який час, що віддає без дублікатів і кому, що продає за якою ціною. Створивши такий простір індивідуального суверенітету, ми знову станемо собою.
[…]
Сучасна ідеологія шерингу, хоч би якою привабливою вона була, маскує масовий грабіж на користь агрегаторів даних. Регулювання — таке, яке передбачає «Регламент захисту даних», — встановило в цьому будинку двері, але не замок: воно лише змушує нас все частіше кликати по «Я згоден». Відтепер усі ці чужі люди запитують у нас: Я зайду на хвилинку, якщо ви не проти? — вже переступивши поріг. Їм важко відмовити. Право власності на дані встановить на двері замки, перевернувши владні відносини і створивши зону спокою, необхідну для розвитку незалежної особистості. Господар наперед складе список гостей, поставивши договірні умови, на яких він готовий повідомляти свої дані. Гоббс в Левіафані питав: хто, лягаючи спати, не зачинятиме двері на ключ? «Однак ніхто з нас не звинувачує людську природу саму собою. Бажання та інші людські пристрасті власними силами є гріхом». Ніхто не ображатиметься на платформи за те, що вони збирають дані, які ми їм даруємо від щирого серця. Але настав час діяти прагматично і поставити замок, якщо ми хочемо зберегтися як індивіди в епоху ШІ.
Зокрема, можна припустити, що дані кожного зібрані в особистому цифровому гаманці. Ми наперед встановимо у смарт-контракті наші власні умови користування, плід особистої деліберації. Як, з ким та в обмін на що ми готові ділитися нашими особистими даними та якими саме? Різні сайти, програми та платформи, зв’язавшись з нами, тут же будуть проінформовані про наші умови. Це вони повинні їх приймати, а не навпаки. Наприклад, я можу вирішити безкоштовно надати дані про своє здоров’я для дослідницьких цілей, але притримати всі дані про геолокацію, хай навіть мені доведеться оплачувати сервіси на кшталт Waze, які їх сьогодні використовують. Щодо даних про мої електронні покупки, я погоджуся передавати їх без особливих проблем, щоб отримувати рекомендації, заточені під мене (і під час справи мати за це грошову компенсацію). Щось на кшталт блокчейну могло б забезпечити можливість відстеження моїх даних, щоб зберігати «пам’ять» про вихідні умови мого договору: подібна процедура вже використовується у музичній індустрії для охорони прав інтелектуальної власності на музичні композиції. Нескінченні фінансові потоки порядку мікросантиму безперервно створюватимуть дебет і кредит у нашому цифровому гаманці, і при цьому обов’язково з’являться посередники для переговорів щодо вартості даних, за зразком товариств з охорони авторських прав. На зміну цифровому феодалізму прийде ціла економіка нескінченно малого ринку, яка сама керуватиметься ШІ. подібна процедура вже використовується у музичній індустрії для охорони прав інтелектуальної власності на музичні композиції. Нескінченні фінансові потоки порядку мікросантиму безперервно створюватимуть дебет і кредит у нашому цифровому гаманці, і при цьому обов’язково з’являться посередники для переговорів щодо вартості даних, за зразком товариств з охорони авторських прав. На зміну цифровому феодалізму прийде ціла економіка нескінченно малого ринку, яка сама керуватиметься ШІ. подібна процедура вже використовується у музичній індустрії для охорони прав інтелектуальної власності на музичні композиції. Нескінченні фінансові потоки порядку мікросантиму безперервно створюватимуть дебет і кредит у нашому цифровому гаманці, і при цьому обов’язково з’являться посередники для переговорів щодо вартості даних, за зразком товариств з охорони авторських прав. На зміну цифровому феодалізму прийде ціла економіка нескінченно малого ринку, яка сама керуватиметься ІІ.
Фінансовий аспект, який передбачається правом власності, ставить закономірні питання. З одного боку, чому ми повинні платити, хай і дуже скромну суму, за послуги, які досі надавалися безкоштовно? Хіба мало заборонити використання особистих даних у комерційних цілях, у логіці «Регламенту про охорону даних»? Але тоді розвалиться вся модель цифрової економіки, позбавивши нас численних послуг, які може надати ШІ. Якщо ми вважаємо, що за виробництво вартості належить винагорода, тоді ця логіка торгового обміну повинна однаково застосовуватися і до індивіда, який виробляє дані, і до платформи-агрегатора. Якщо Waze вибирає для мене найкращий маршрут, але при цьому я відмовляюся від реклами ресторанів, що знаходяться на цьому маршруті, необхідно знайти інші способи відшкодування шкоди платформам. В іншому випадку я стану «безбілетником», який користується чужими даними, нічим не поділяючись натомість. Анонімність має власну ціну.
[…]
На боці ШІ власність на особисті дані призведе до втрати ефективності, з чим доведеться упокоритися всьому суспільству. Будь-кого порадує, що прибутки Facebook постраждають через втрату точності в таргетуванні реклами, проте та сама неоптимальність торкнеться й інших громадських послуг. Можна, звичайно, уявити, що окремі категорії особливо важливих для суспільства даних будуть «націоналізовані», подібно до того, як дозволено вилучати землю у приватних землевласників для будівництва життєво важливих об’єктів інфраструктури. Але така процедура може мати лише надзвичайний характер, і рішення про неї має прийматися судом, який встановить, якою мірою експропріація відображає мотив загального інтересу. В інших випадках доведеться визнати, що розумне місто чи розумні лічильники вже не будуть настільки розумними, а безпілотні автомобілі настільки безпілотними. Допустивши можливість індивідуального відхилення, право власності на дані викличе аварії, вуглецеві викиди та розриви відносин. Воно завадить суспільству стати ідеальним, повернувши цим можливість еволюції… як регресії. Терпіти подібні випадковості, безпосередні та конкретні, заради розпливчастої обіцянки прогресу — тяжкий тягар для законодавців. Але саме на цій лінії розлому відбувається боротьба міжnudge і автономією, щасливим рабством та поверненням епохи освіти.
Вже зараз є чимало стартапів, які б хотіли взяти участь у цій війні за повернення людині автономії. Такі екосистеми особливо динамічно розвиваються у Франції — країні, яка вигадала авторське право. У Парижі, Ліоні, Монпельє підприємці прагнуть вдихнути життя в це право власності, в якому регулятор поки що відмовляє. Одні розробляють data wallet: використовуючи передбачене GDPR право на мобільність, він дозволяє кожному отримувати свої особисті дані та контролювати їх надання. Інші шукають спосіб надати персональним даним грошову вартість, користуючись правовими «сірими зонами». Треті організують «цифрові кооперативи», які спільно використовують дані своїх членів і виплачують їм дивіденди. Як це вже неодноразово бувало, технологія змусить право підлаштовуватися під себе. Можливо, об’їхавши всю планету, в результаті я знайду рішення зовсім близько від будинку, як капітан Хеддок, який знайшов скарби Лікорну у Муленсарі?
У цій статті я пропоную вам ознайомитись з основними перевагами Rematch та покажу, як просто та ефективно використовувати його для керування станом ваших додатків. Думаю, що, незалежно від вашого досвіду у розробці, ви знайдете корисну інформацію, яка допоможе вам у повсякденній роботі.
Rematch пропонує зручний синтаксис та дозволяє уникнути написання численних бойлерплейтів, властивих Redux. За допомогою нього ви можете швидко створювати та організовувати Redux-сховище, заощаджуючи при цьому час та спрощуючи процес розробки. Rematch ідеально підходить для різних типів проектів, незалежно від їх розміру та складності.
За допомогою Rematch ви можете визначити моделі (models) та їх стан, ефекти (effects) та ред’юсери (reducers). Він пропонує зручні інструменти для роботи з асинхронними операціями, а також можливість створення селекторів (selectors) для вибірки даних зі сховища. Все це допомагає організувати логіку вашої програми та керувати її станом з мінімальними зусиллями.
Насамперед, я б рекомендував цю бібліотеку тим, хто тільки починає вивчати управління станом додатків або пише новий проект з нуля, тому що Rematch набагато простіше в освоєнні, ніж багато інших бібліотек, забезпечує набагато приємніший інтерфейс і, до того ж, набагато легше.
Введення в Rematch
Rematch – це інтуїтивний та легковажний фреймворк для керування станом вашої веб-додатки на основі Redux. Він пропонує простий та ефективний підхід до організації та управління Redux-сховищем, скорочуючи кількість зайвого коду та спрощуючи розробку.
Rematch — це інструмент для управління станом, а й філософія розробки. Він ставить собі завдання зробити код більш зрозумілим, легко підтримуваним і масштабованим. Однією з ключових особливостей Rematch є його інтеграція з Redux без необхідності писати численні бойлерплейт-коди та налаштування. Це дозволяє розробникам швидше почати ним користуватися та зосередитися на бізнес-логіці своєї програми.
У процесі роботи з бібліотекою я наголосив на наступних її корисних рисах:
невеликий обсяг (менше 2Кб);
відсутність необхідності зміни;
вбудована підтримка сайд-ефектів;
підтримка Redux Devtools, TypeScript;
підтримка динамічного додавання ред’юсерів, гарячого перезавантаження;
можливість створення кількох сховищ;
розширюваність функціоналу за допомогою плагінів;
можливість використання у React Native.
Якщо порівнювати Rematch із прямим використанням Redux, його основні переваги:
Простота та зрозумілий синтаксис . Rematch пропонує просту та інтуїтивно зрозумілу модель, яка дозволяє визначити моделі стану, ефекти та редьюсери з мінімальною кількістю коду. Він звільняє розробників від необхідності писати численні дії (actions), константи та редьюсери, що робить код лаконічнішим і зрозумілішим.
Модульність і перевикористовуваність . Rematch дозволяє організовувати код вашої програми у модулі (моделі), що сприяє логічному поділу функціональності та повторному використанню коду. Ви можете створювати незалежні моделі, що містять свій стан, ред’юсери та ефекти, та комбінувати їх в одне сховище.
Потужні ефекти . Rematch надає простий спосіб визначення та обробки асинхронних операцій та сайд-ефектів за допомогою ефектів. Він інтегрується з middleware Redux, що дозволяє легко керувати асинхронними запитами, зверненнями до API та іншими ефектами сайду.
Розширюваність . Rematch дозволяє легко розширювати функціональність за допомогою плагінів. Ви можете використовувати готові плагіни або створити свої власні, щоб додати нові можливості та інтеграції у свою програму.
Незважаючи на представлені плюси, важливо розуміти, що Rematch – це лише обгортка над Redux, яка надає розробникам спрощене API. Проблеми продуктивності та додаткового функціоналу, на жаль, не вирішить перехід від використання Redux до Rematch.
Основні концепції Rematch
Тут я покажу основні концепції Rematch, які допоможуть вам організувати та керувати станом вашої програми.
Моделі (Models)
Моделі є ключовим поняттям у Rematch. Вони є незалежними блоками коду, що містять стан, ред’юсери та ефекти. Кожна модель має унікальне ім’я і може бути поєднана з іншими моделями в одне сховище (store).
Давайте створимо просту модель “counter”, яка міститиме стан лічильника та редьюсери для його збільшення та зменшення, а також ефект для асинхронного збільшення:
Сховище є об’єднання декількох моделей в одну структуру даних. Воно є єдиним джерелом правди для вашої програми та зберігає стан усіх моделей.
Для створення сховища Rematch використовує функцію init, яка приймає об’єкт із моделями:
import { init, RematchDispatch, RematchRootState } from"@rematch/core";
import { models, RootModel } from"./models";
exportconst store = init({
models,
});
export type Store = typeof store;
export type Dispatch = RematchDispatch<RootModel>;
export type RootState = RematchRootState<RootModel>;
Диспатч екшенів (Dispatch actions)
За допомогою диспатча ви можете викликати редьюсери та ефекти ваших моделей. Диспатч можна викликати звичним способом, як у Redux, або коротким записом:
У цьому прикладі ми використовуємо хук useSelector для отримання значення стану “counter” зі сховища, а також метод dispatch для виклику відповідних редьюсерів.
Ефекти (Effects)
У Rematch ефекти надають можливість виконувати асинхронні операції, такі як запити до сервера чи обробка даних. Вони дозволяють вам легко керувати побічними ефектами у вашому додатку.
Для додавання ефектів у модель можна використовувати ключове слово effects і визначити потрібні методи. Давайте додамо ефект для завантаження даних із сервера:
Rematch надає можливість розширення функціональності за допомогою плагінів. Плагіни дозволяють додавати додаткові можливості або змінювати поведінку Rematch, щоб краще відповідати вашим потребам. Вони можуть перевизначити конфігурацію, додати нові моделі або навіть замінити все сховище.
Існує безліч плагінів, доступних для використання з Rematch. Деякі з них були написані безпосередньо командою авторів цієї бібліотеки, але є такі, які створювалися спільнотою, на npm/github, і ніхто не забороняє написати свій власний плагін.
Нижче ви знайдете короткий опис плагінів, створених командою Rematch:
@rematch/immer : Обертає ваші ред’юсери за допомогою бібліотеки immer, що дозволяє безпечно виконувати зміни стану за допомогою мутацій, зберігаючи при цьому незмінність стану.
@rematch/select : Додає можливість використовувати селектори (selectors) для вибору даних стану. Селектори створюються за допомогою бібліотеки reselect за замовчуванням і автоматично зв’язуються із залежностями селекторів з інших моделей.
@rematch/loading : Плагін для відображення індикаторів завантаження під час виконання ефектів. Допомагає уникнути ручного керування станом завантаження, додаючи автоматичну підтримку завантаження Rematch.
@rematch/updated : Плагін, що дозволяє підтримувати тимчасові мітки (timestamps) під час виклику ефектів. Він застосовується переважно для оптимізації ефектів і може використовуватися для запобігання виконання дорогих запитів протягом певного періоду часу або обмеження частоти виконання ефектів.
@rematch/persist : Надає автоматичну персистентність стану Redux. Це дозволяє зберігати стан між перезавантаженнями сторінки або після закриття та повторного відкриття програми.
@rematch/typed-state : призначений для перевірки типів стану під час виконання. Використовує proptypes для опису очікуваної форми типів.
Підсумок
У цій статті я розповів про Rematch – потужну бібліотеку для управління станом додатків. На підставі свого досвіду виділив основні переваги Rematch і на практиці показав, як легко та ефективно використовувати його для організації Redux-сховища та управління станом.
Rematch пропонує простий та зручний синтаксис, який значно зменшує кількість бойлерплейту, пов’язаного з Redux, і я думаю, що це може зробити його привабливим інструментом для простих розробників, які хочуть зосередитися на розробці програми, а не на складностях управління станом.
Завдяки підтримці безлічі плагінів, Rematch може бути легко розширений та адаптований під ваші конкретні потреби. Ми розглянули деякі популярні плагіни, такі як плагін для збереження стану за допомогою redux-persist, плагін для використання immer.js та плагін для створення селекторів за допомогою reselect.
Зазначу, що Rematch постійно розвивається та покращується, і ви можете досліджувати додаткові можливості, вивчивши вихідний код плагінів або створюючи власні плагіни.
Сподіваюся, що ця стаття допомогла вам зрозуміти переваги та можливості Rematch та надихнула вас використовувати його у ваших проектах. Бібліотека пропонує простоту, компактність та масштабованість, роблячи процес розробки більш ефективним та приємним.
Відмінності базових елементів блокчейн: чому ця технологія не здатна здійснити революцію
Такі слова, як Біткоїн та блокчейн іноді використовуються як взаємозамінні, але насправді між ними є деякі непорозуміння. Такої думки дотримується Кевін Вербах, професор юридичних наук та ділової етики Уортонської школи бізнесу. Він заявив про те, що в технології блокчейн базові елементи мають певні відмінності, при цьому йдеться про криптовалюту, криптоаналіз і саму блокову систему.
У наші дні важко не помітити ажіотажу навколо заяв про те, як криптовалюти та технологія blockchain можуть змінити все (або принаймні зробити багато). Тим не менш, такий галас навколо цього є ризиком масштабної афери, марною і небезпечною. Дивно, що така величезна аудиторія досі не розуміє, що відбувається. Однією з головних причин плутанини є те, що всі говорять про різні речі.
Представники угруповань усіх трьох складових блокчейну поділяють базовий набір принципів проектування та технологічних основ, але в цілому їх цілі та перспективи практично повністю відрізняються один від одного. Спробуймо розібратися в ситуації.
Існує криптовалюта — ідея, що мережі можуть безпечно передавати цифрові активи без центральних точок контролю. Існує блок-ланцюжок — ідея про те, що мережі можуть колективно досягати консенсусу щодо інформації через встановлені межі довіри. І є криптоаналіз — ідея про те, що віртуальні валюти можуть відігравати роль активів, що торгуються.
Перше – воістину революційне поняття, але це ще не знає, що революція буде успішною. Друге та третє — інновації, що змінюють гру та здатні до суттєвого еволюціонування.
Криптовалюти
Цифрові гроші — це те, про що багато хто, напевно, чув найбільше, починаючи з Bitcoin. Найпростіший спосіб зрозуміти їх – не вивчати деталі майнінгу чи внутрішнього пристрою. Натомість краще зосередитися на децентралізації довіри.
Багато дій потребують довіри. Без довіри проект закону вартістю кілька мільйонів доларів — це лише аркуш паперу, а голосування на виборах — безглуздий ритуал. Традиційно під словом «довіра» малася на увазі залежність від партнерів, установ чи посередників. Ці централізовані архітектури довіри є сильними. Серед іншого, вони принесли нам сучасну індустріальну цивілізацію. Але є й недолік у довірі. Він має на увазі вразливість. Люди, уряди та компанії, яким ми довіряємо, можуть виявитися ненадійними з низки причин. Біткоїн показав, що можна створити щось цінне (наприклад, гроші), яким можна довіряти без необхідності довіряючи конкретній особі чи організації, зокрема щодо перевірки транзакцій.
Ця ідея, якщо вона буде повністю реалізована (у разі «якщо» несе у собі крані важливий сенс), може змінити суспільство. Світ може отримати прозорі компанії, які справді відображають волю зацікавлених у їхньому розвитку сторін, уряди, які справді відображають волю своїх громадян, та інтернет, звільнений від цензури та впливу ззовні. Це здатне покласти край фейковим новинам та масової автоматизації повсякденного життя для покращення рівня життя людства. Або принаймні люди можуть отримати рішення, які помітно покращать їхній статус-кво. Децентралізація несе у собі цінність у вигляді незалежно від способу.
Витрати
Цей термін застосовується практично до всіх сфер діяльності. Для Біткоіна витрати пов’язані з дуже повільною мережею з обмеженою функціональністю, яка витрачає величезну кількість електроенергії та збагачує співтовариство майнерів. Можливо, це того варте. Однак, можливо, у майбутньому технологічні рішення завдяки удосконаленню блокової технології призведуть до зниження витрат. Поки що ми цього не знаємо. Так, ринкова капіталізація Біткоїна становить мільярди доларів, але це насправді просто криптоаналітичне мислення. Хтось використовує його, щоб робити щось, окрім прагнення розбагатіти шляхом торгівлі чи уникнути уваги з боку правоохоронних органів? Він стає все гіршим і гіршим, тому що на ринку з’являються все нові і нові криптовалюти. Деякі з них не поступаються,
Прибуток
Що справедливо для невеликих груп, обмежених програм та «особливих» користувачів, не обов’язково може стати мейнстримом. Доки не з’явився Facebook, було неясно, хто і як може заробляти реальні гроші на соціальних мережах, які спочатку були місцем простого спілкування підлітків і молоді. Однак сам факт появи Facebook не доводить, що це було неминучим.
Деякі зі ставок на криптовалютну революцію можна довести правильно. Такі ставки мають широкий потенціал зростання, але насправді це все ж таки просто гра. Насправді реальні революції відбуваються не так часто. І коли це трапляється, то відбувається із серйозними побічними збитками.
Blockchain
Блокчейн має спільне коріння з криптовалютами, але його мета зовсім інша. Замість спроби уникнути довіри блокчейн прагне надмірно обмежити довіру. Ми справді довіряємо собі чи своїй власній організації. Але жодна людина чи компанія не є островом в океані. Але навіть острівні держави змушені взаємодіяти з іншими учасниками світу через воду.
Світ наповнений процесами, особливо серед великих компаній та урядів, де їх слід відстежувати з однієї довіреної зони до іншої. Фірми щорічно витрачають близько $10 трлн на «логістику», що скорочує витрати на транспортування через системи, контрольовані кимось. Виробники, дистриб’ютори та роздрібні торговці зберігають власні надійні (але незалежні) записи даних про потоки через ланцюжки поставок.
Коли пацієнт йде в нову лікарню або до нового лікаря, то не маєте при собі всіх медичних записів через відсутність єдиної бази. Усі такі недоліки в потоці інформації є своєрідними транзакційними витратами. Відповідно до сьогоднішньої домінуючої школи економіки, зусилля зі знищення цієї проблеми є важливою рушійною силою в економіці.
Значна частина транзакційних витрат між фірмами (іноді і всередині них) випливає з обмеженої еластичності довіри. Якщо кожна сторона транзакції довіряє залученій інформації, навіть якщо вони не довіряють одна одній, витрати можуть знизитися, а продуктивність різко змінитись. У цьому полягає суть бачення блочної ланцюжка.
Багато відомих компаній вже беруть участь у всіх процесах блокових випробувань і консорціумах, тому що бачать у цьому величезний потенціал. Децентралізація в цьому випадку має інше бачення, а не просто базову вимогу, як у випадку з криптовалютами.
Криптоаналіз
Під цим терміном розуміється аналіз цифрових токенів, які перетворюються на інструменти торгівлі. Потенційна шкала цього напряму величезна. Обсяги ринків досягають трильйони доларів, що не можна назвати незвичайним у сучасній фінансовій сфері. При цьому вони розглядаються не як спосіб полегшення дій без централізованої довіри, а як новий клас інвестиційних активів. Оскільки вони є цифровими, вони можуть теоретично торгуватися більш ефективно, ніж існуючі інструменти. За своєю суттю вони гнучкіші і глобальніші. Практично всі основні гравці Уолл-стріт прагнуть взяти участь у різних стартапах у ролі інституційних інвесторів.
Як тільки буде встановлено фундаментальне значення цифрових токенів у децентралізованій мережі, чому б просто не використовувати їх для заробляння грошей? У будь-якому випадку вони залежатимуть від криптовалюту, бо торгівля можлива лише чимось справді цінним. Однак вони також мають бути безпечними. Але криптоаналіз ігнорує чи відкидає ідею криптовалют про те, що довіра — «майже непристойність» (вирізка з цитати експерта, який робив початковий аудит безпеки Біткоіна ). Для трейдера криптоаналіз довіри та відсутність довіри — це не що інше, як засіб для досягнення мети, що називається ліквідністю.
Інший спосіб подумати про це полягає в тому, що криптоаналіз передбачає свого роду злиття функцій токенів та криптовалют. Якщо ви хочете використовувати Біткоїн для оплати покупок, Ефіріум для придбання обчислювальних циклів для розподілених додатків, Filecoin для покупки хмарного сховища файлів або Augur Rep для перевірки результатів ринків прогнозів, ви забезпечуєте цінність цих токенів на основі того, що ви отримуєте за рахунок їх використання.
Теоретично велика потреба у використанні додатків означає скорочення пропозицій і зростання попиту, що штовхає курс вгору. На практиці поки що жодна з додатків не має істотної важливості, тому ціна токенів залишається дуже спекулятивною. Спекуляцію не обов’язково завжди розглядати як щось погане. Це апетит до ризику, який керує фінансовими ринками. Однак іноді спекуляція стимулює ринки рости надто високо. Ключовим питанням для криптовалют є питання про те, чи можна буде контролювати такі умоглядні інстинкти.
У процесі розвитку ринків можуть виникати різні цікаві можливості для «токенізації» фізичних предметів, таких як товари, нерухомість, цифрові речі, такі як інтелектуальна власність та інші види прав, з використанням інструментів фінансової інженерії та аналітики. У цьому напрямі Уолл-Стріт розвивається вже багато років, створюючи необхідні основи.
Не варто перетинати межу
Історії не є взаємовиключними як такі. Успіх чи невдача якогось бачення не обов’язково означають, що аналогічне може статися з іншим. Криптовалюти мають найруйнівніший потенціал, бо вони обіцяють децентралізувати владу. Це також створює великі перешкоди для їхнього успіху.
Як блокові системи, і цифрові валюти зменшують децентралізацію серед інших своїх переваг. Вони різняться в цілях і можуть мати значні можливості, але їх потрібно оцінювати зі свого погляду. Наприклад, чи варто розглядати ICO як нову форму краудфандингу чи спосіб започаткувати децентралізовану економіку? Те, що вважається успішним чи невдалим, виглядає по-різному залежно від відповіді.
Будь-які судження про успіхи або невдачі, пов’язані з блоковою технологією, повинні бути сформульовані з точки зору відповідної підкатегорії. Коли спостерігачі вказують на прийняття блокчейна тією чи іншою компанією або високі ціни на криптовалюти як доказ їхньої життєздатності, вони перетинають межу. Той факт, що у світі ICO існує масове шахрайство та крадіжки, ніяк не належить до низки урядових ініціатив у сфері блокчейну.
Незалежно від того, чи йдеться про бізнес-модель, яка передбачає впровадження блокового ланцюжка в банки, цього недостатньо, щоб говорити про перспективи децентралізованих автоматизованих організацій загалом.
Чим раніше ми перестанемо розглядати блокчейн і криптовалюти як унітарне явище, тим точніше і якісніше ми зможемо оцінити події, що відбуваються.
Співвідношення ризику та прибутку при торгівлі криптовалютою та чому це важливо
Співвідношення ризику та прибутку – коефіцієнт, призначений для розрахунку потенційної прибутковості від торгової угоди щодо закладеного ризику та з урахуванням стратегії трейдера. RR дозволить зрозуміти, чи є угода вигідною чи ні.
Співвідношення ризику та прибутку розраховується після складання торгового плану, визначення точок входу та виходу та рівня встановлення стоп-лосса.
Співвідношення ризику та прибутку розраховується індивідуально для кожної позиції на підставі торгової стратегії трейдера з урахуванням статистики та можливостей.
Грамотне співвідношення ризику та прибутку дозволяє заробляти у довгостроковій перспективі при правильному аналізі результатів своєї торгової стратегії.
Що таке співвідношення ризику та прибутку (RR)
Співвідношення ризику та прибутку (Risk/Reward Ratio або RR) – коефіцієнт, що показує співвідношення ризику до потенційного прибутку. Конкретне значення RR розраховується перед покупкою активу та дозволяє оцінити потенціал угоди з погляду торгової стратегії трейдера.
Якщо співвідношення ризику до прибутку більше значення 1, то ризик більший, ніж потенційний прибуток. Коли значення нижче одиниці, то потенційний прибуток більший за закладені ризики.
З погляду трейдингу та інвестицій ризик означає потенційний збиток, який трейдер готовий піти, відкриваючи позицію. Рівень ризику зазвичай контролюють за допомогою виставляння ордерів стоп-лосс (Stop Loss), тобто заявок на автоматичний продаж активу при досягненні певної ціни. Це важливий торговий інструмент, і необхідний як обмеження збитків. Рівень ризику є невід’ємною частиною у процесі обчислення потенційного прибутку трейдера та його торгової стратегії загалом.
Прибуток — це різниця між ціною купівлі активу та ціною, за якою його буде продано. У контексті співвідношення RR прибутком є потенційний рівень, який визначає трейдер перед входом до позиції для оцінки потенціалу торгової операції.
Як правильно розрахувати співвідношення ризику та прибутку
Загальноприйнятий варіант розрахунку коефіцієнта RR визначається як відношення ризику до прибутку, тобто RR дорівнює ризик поділений на прибуток. Хоча деякі трейдери через особисті переваги можуть використовувати зворотний варіант, де прибуток ділять на ризик, ми розглянемо стандартний приклад розрахунку.
Припустимо, що бажаєте придбати актив за ціною $100. Ви також вирішили обмежити ризик, тобто поставити стоп-лосс, на позначці $90, і встановили собі цільову ціну, за якою продасте актив, на позначку $130. У цьому випадку співвідношення RR складе 1 до 3 або коефіцієнт з приблизним значенням 0,33. Тобто ризик менший, ніж потенційний прибуток.
У прикладі з тією ж ціною входу ($100), і такою ж цільовою ціною ($130), але з виставленим стоп-лоссом на відмітці $40, співвідношення RR буде рівним 2. Таке значення коефіцієнта вказує, що ризик значно перевищує очікуваний прибуток.
Оптимальне співвідношення ризику та прибутку
Одним із найпопулярніших значень при розрахунках співвідношення ризику та прибутку є 1 до 3 або коефіцієнт 0,33. Також часто використовуються співвідношення 1 до 7, 1 до 10, 1 до 15.
Однак вибір загальноприйнятих варіантів RR є грубою помилкою у трейдингу. Трейдер повинен сам визначити, яке співвідношення RR найкраще підходить під його торгову стратегію на основі досвідчених даних, статистики, кон’юнктури ринку.
Наприклад, якщо трейдер робить тільки 50% успішних угод, то RR рівний 0,5 або 1 до 2 не принесе користі. Цільова ціна продажу активу перед входом до угоди має статистично приносити трейдеру прибуток, а не тільки саме в цій торговій операції.
У прикладі із співвідношенням 1 до 3 або коефіцієнтом 0,33, сенс RR закладено в тому, щоб одна прибуткова угода могла покрити 3 збиткові угоди. У разі коли співвідношення 1 до 5, то одна прибуткова угода повинна буде покрити 5 збиткових.
Перш ніж оцінювати ризики та проводити розрахунки RR, трейдер оцінює потенціал руху ціни, знаходить точку для входу і становить прогноз руху ціни на актив, також визначивши собі момент виходу з позиції.
Тільки після цього є сенс проводити розрахунки RR. Якщо отриманий коефіцієнт відповідає торговій стратегії трейдера, він входить у позицію.
Навіщо розраховувати співвідношення ризику та прибутку
RR розраховується для того, щоб трейдер міг ефективно використовувати свою торгову стратегію, регулюючи потрібний рівень ризику та прибутку для отримання прибутку на довгому відрізку часу.
Навіть якщо відсоток успішних операцій невеликий, скажімо 20%, грамотне співвідношення ризику і прибутку може принести трейдеру дохід на довгій дистанції.
Відповіді на популярні запитання
Що таке співвідношення прибутку до ризику?
Risk/Reward Ratio або RR – це спосіб оцінити потенціал угоди для трейдера на основі його торгової стратегії та можливостей. Простіше кажучи, RR показує, чи є угода вигідною чи ні на основі потенційних ризиків та прибутку.
Що таке вінрейт у трейдингу?
Вінрейт у трейдингу – ставлення кількості прибуткових угод до збиткових. Наприклад, якщо ви закриваєте 60% угод із прибутком, а 40% — зі збитком, то ваш вінрейт становитиме 0,6 до 0,4, або 1,5.
Що таке 1 до 3 у трейдингу?
1 до 3 у трейдингу – одне з найпопулярніших співвідношень прибутку до ризику у трейдерів. Воно означає, що як мінімум 1 із 4 угод має бути прибутковою. Проте таке співвідношення має відповідати обраній торговій стратегії та співвідноситися з вінрейтом. У деяких випадках оптимальне співвідношення прибуткових угод до збиткових може відрізнятися.
Що таке RR у трейдингу?
RR у трейдингу – абревіатура від англійського терміна Risk/Reward (Ризик/дохідність) і означає співвідношення прибутку до ризику.
Давайте спочатку познайомимося з обома бібліотеками, щоб порівняти їх і переконатися, що краще. react-query та SWR – це дві популярні бібліотеки для керування станом даних у React-додатках. Вони обидві призначені для полегшення роботи з даними, що отримуються з сервера, але мають деякі відмінності у функціональності та підходах.
react-query
react-query — це потужна бібліотека для керування станом даних у програмах React. Вона надає прості та ефективні інструменти для роботи з даними, що отримуються з сервера, та спрощує взаємодію з API-запитами. Нижче познайомимося з базовими фічами цієї бібліотеки:
Кешування даних: Однією з основних можливостей react-query є кешування даних. Під час виконання запитів до сервера бібліотека автоматично кешує отримані дані. Це дозволяє уникнути повторних запитів на сервер при зверненні до тих самих даних у різних частинах програми. Кеш react-query також автоматично інвалідується під час оновлення даних на сервері або вручну за допомогою інвалідності.
queryClient.invalidateQueries()
Автоматичне оновлення даних: react-query надає механізм автоматичного оновлення даних на основі певних подій. Коли запит на сервер виконується, бібліотека автоматично оновлює кешовані дані при успішному завершенні запиту, мутації або ручних викликах оновлення. Це дозволяє завжди мати актуальні дані у додатку.
Повторні запити: У разі помилок під час виконання запиту react-query надає механізм повторних запитів, який автоматично спробує повторити запит. Це особливо корисно під час роботи з нестабільним інтернет-з’єднанням або тимчасовими проблемами на стороні сервера. Також можна налаштувати інтервал між повторними запитами або вказати максимальну кількість повторів у налаштуваннях.
Оптимістичні оновлення: React-query підтримує оптимістичні оновлення даних. Це дозволяє оновлювати кешовані дані негайно ще до того, як запит на сервер буде завершено. Це створює плавне враження для користувачів та підвищує чуйність інтерфейсу.
Обробка помилок та повторні запити: Бібліотека спрощує обробку помилок під час виконання запитів. Вона надає механізм повторних запитів під час помилок, що дозволяє автоматично спробувати повторити запит для отримання даних. Це особливо корисно під час роботи з нестабільним інтернет-з’єднанням або тимчасовими проблемами на стороні сервера.
Гнучка настройка запитів: Бібліотека надає гнучкі засоби для налаштування запитів, дозволяючи контролювати кешування, час життя даних, політики повторних запитів та багато іншого.
Мутації: react-query підтримує мутації, що дозволяє легко виконувати зміни даних на сервері. Мутації є особливими функціями, які виконують запити на сервер для зміни даних, і автоматично оновлюють відповідний кеш після успішного завершення мутації.
Інтеграція з React: react-query розроблена спеціально для роботи з React та інтегрується з ним без проблем. Вона надає хуки та компоненти, які дозволяють зручно взаємодіяти з даними та відображати їх в інтерфейсі React-компонентів.
SWR (Stale-While-Revalidate) – це бібліотека для керування станом даних у React-додатках, яка орієнтована на кешування даних та автоматичну валідацію. Вона надає простий та ефективний спосіб роботи з даними, що отримуються з сервера, та спрощує оновлення даних в інтерфейсі програми. Нижче познайомимося з базовими фічами цієї бібліотеки:
Кешування даних: Однією з основних можливостей SWR є кешування даних, які отримують із сервера. Коли запит на сервер, бібліотека автоматично кешує отримані дані. Це дозволяє уникнути повторних запитів на сервер при зверненні до тих самих даних у різних частинах програми.
Автоматична валідація даних: SWR використовує стратегію Stale-While-Revalidate, що означає, що вона повертає старі дані з кешу (якщо вони доступні) і одночасно запускає повторний запит на сервер для отримання актуальних даних. Таким чином користувач завжди бачить старі дані, навіть якщо сервер вже повернув нові. Це дозволяє надати користувачеві миттєвий відгук та актуальні дані після завершення повторного запиту.
Повторні запити: У разі помилок під час виконання запиту SWR надає механізм повторних запитів, який автоматично спробує повторити запит. Це особливо корисно під час роботи з нестабільним інтернет-з’єднанням або тимчасовими проблемами на стороні сервера.
Оптимістичні оновлення: SWR також підтримує оптимістичні оновлення даних. Це означає, що при оновленні даних на сервері вона моментально оновлює дані в кеші і показує користувачеві оновлені дані без очікування відповіді від сервера. Після успішного завершення запиту на сервер кеш автоматично оновлюється з актуальними даними.
Політики повторних запитів: SWR дозволяє гнучко налаштовувати повторні запити за допомогою різних політик. Наприклад, можна встановити інтервал між повторними запитами або вказати максимальну кількість повторів.
Інтеграція з React: SWR розроблена для інтеграції з React і надає хук useSWR(), який дозволяє зручно взаємодіяти з даними та обробляти стан запитів.
Тепер, давайте порівнювати ці дві бібліотеки та визначити, який краще вибрати:
Як ми зрозуміли, основний акцент бібліотеки react-query робиться на керування даними на клієнтській стороні програми, особливо на роботу з даними, що отримуються з сервера (API-запити). react-query пропонує потужні засоби для кешування даних, автоматичної інвалідності кешу та обробки запитів.
SWR в першу чергу орієнтована на кешування та автоматичну валідацію даних, які отримують з сервера. Вона надає зручні засоби для кешування та повторних запитів даних із підтримкою стратегії “Stale-While-Revalidate” (збереження старих даних, поки виконується повторний запит).
Також react-query надає гнучкі засоби для налаштування запитів та підтримує мутації, дозволяючи легко виконувати зміни даних на сервері, для цього react-query надає хуки ( useMutation(), useQuery()) та компоненти для зручної взаємодії із запитами та мутаціями. SWR у свою чергу надає лише один хук — useSWR, який дозволяє виконувати запити та автоматично кешувати дані, а також обробляти їх оновлення та помилки.
Підсумок
Загалом, якщо ваш проект величезний і має багато GET/POST запитів, краще використовувати react-query, якщо проект не великий і не має багато запитів, то краще вибирати SWR. Все залежить від обсягу та функціональності проекту.
Тепер відповімо на найголовніше запитання: «Чи позбавимося ми Redux?». Насправді повністю позбутися Redux не вийде, але певною мірою, так, позбудемося. Як? У всіх запитах, де використовується react-query/SWR використовувати Redux не потрібно, ці бібліотеки самі всі дані беруть з бекенда і працюють як “state manager”, а також плюс до цього кешують дані, що це навіть дуже вигідно.
“У комп’ютерній науці всі проблеми можуть бути вирішені за допомогою додаткового рівня непрямості,” – Девід Вілер
Типи даних – це природно
Людина є істотою з дуже розвиненим образним мисленням. Саме наша здатність до створення абстракцій та узагальнення прожитого досвіду стала ключем до розвитку цивілізації. Ми користуємося цими здібностями від народження, навіть не замислюючись. Наприклад, ми з дитинства працюємо з різними типами даних, діючи швидше інтуїтивно, не даючи їм формального опису. Ми знаємо, що числа можна складати і множити, а зі слів складати речення. Навряд чи нам спаде на думку спробувати перемножувати слова. Таким чином, ми розуміємо, коли бачимо написані символи (літери, наприклад), що ми можемо і чого не можемо робити з цими символами, а також знаємо набір допустимих значень символів — наш алфавіт. У прикладі літери — і є тип даних. Ми знаємо безліч значень літер — вони є алфавітом. Крім того, знаємо, що літери ми можемо складати слова – це операції. Це природне уявлення людини лягло основою формального визначення типу даних.
Тип даних – безліч значень та [допустимих] операцій над цими значеннями.
Хоча ми в житті не використовуємо це визначення і навіть не замислюємося про це, кожен день ми стикаємося з різними типами даних: літери, цифри, предмети побуту, продукти харчування. Але навіть при вирішенні побутових питань може виникнути ситуація, коли наявних у розпорядженні простих типів даних може бути недостатньо.
Уявіть собі такий діалог матері та маленького сина років трьох, який ще не дуже освоїв абстрактне мислення:
— Синку, принеси, будь ласка, зі столу ручку, мені треба записати щось!
– Мамо, тут немає ручки!
– Тоді олівець.
– І олівця немає.
– А що є?
— Фломастери є й маркер.
– Ну, тоді неси фломастер!
Доросла людина швидше за все відразу принесла б фломастер і сказала: «ручки не було, думаю, фломастер пригодиться». Чому? — Тому що з якогось рівня розвитку абстрактного мислення та вміння взаємодіяти з іншими людьми людина вже розуміє, що в цьому проханні головне не конкретний тип об’єкта — ручка — а її властивість писати по папері. Таку ж властивість мають й інші об’єкти: олівці, фломастери, маркери, навіть шматочок вугілля. Таким чином, він машинально поєднує кілька типів інструментів в один тип: те, чим можна писати. Це вміння часто спрощує нам повсякденне життя та спілкування з оточуючими, при цьому дещо віддаляючи нас від конкретних фізичних об’єктів. Щоб дістатися роботи, ми використовуємо «громадський транспорт» — маршрути та конкретні вагони чи машини можуть бути різними, але головне, що вони мають потрібні нам властивості: ми можемо увійти, вийти, сплатити за проїзд, ми заздалегідь впевнені в тому, що це можна зробити з кожним з об’єктів цього типу. Коли ми в незнайомому місті хочемо сходити в кафе, ми запитуємо у друзів або в інтернеті: «де в місті Н можна смачно поїсти?», тобто ми не визначаємо конкретний заклад, навіть його тип, а ставимо в основу найважливішу властивість групи закладів: ми можемо прийти туди та замовити їжу.
Іншими словами, у деяких ситуаціях нам важливий не об’єкт конкретного типу, а певні його властивості: тобто, що ми можемо з ним робити. Часто шуканими властивостями володіють кілька типів даних, і всі вони нам так чи інакше підійдуть, як описані вище приклади. Це призводить до визначення абстрактного типу даних. Спочатку наведемо формальне визначення, а потім розкриємо його у більш простих термінах.
Абстрактний тип даних (АТД) – це математична модель для типів даних, де тип даних визначається поведінкою (семантикою) з точки зору користувача даних, а саме в термінах можливих значень, можливих операцій над даними цього типу та поведінки цих операцій.
Що таке математична модель? Хто такий користувач даних? Що мають на увазі під поведінкою операцій? Навіщо взагалі так ускладнювати? Давайте розумітися.
Заглиблюємося в деталі та розбираємо приклади
Щоб не перевантажувати себе новою інформацією, давайте будемо під математичною моделлю об’єкта або явища розуміти просто його формальний опис. Повертаючись, наприклад, з мамою, якій знадобилася ручка, ми можемо переробити її прохання в такий спосіб: «Сину, принеси мені, будь ласка, якийсь інструмент, який може залишати контрастні сліди на папері і при цьому поміщається до мене в руку». Звучить на побутовому рівні досить абсурдно, але саме це і буде формальним описом того, що знадобилося мамі.
Рухаємось далі. Уявімо програміста, перед яким стоїть завдання створення системи електронної черги в травмпункті.
При надходженні до травмпункту людині видається талон з номером (порядковим номером відвідувача травмпункту) та визначається пріоритетність черги: його травма оцінюється за шкалою від 1 до 10, де 10 – травма, яка потребує негайної медичної допомоги. Необхідно реалізувати механізм додавання людини до черги та визначення наступного пацієнта на прийом.
Для вирішення такого завдання потрібно створити програму, яка використовуватиме в коді деякі дані: номери талонів та їх пріоритети. У коді програми будуть проводитись операції над даними. Як ви побачите далі, ці операції не завжди прості, а можуть містити в собі безліч дій, а також мати деякі наслідки для всієї програми і всіх даних, що зберігаються: важкий пацієнт посуне всю чергу назад, тому що йому потрібна термінова медична допомога. Все в сукупності: набори операцій, дії, з яких вони складаються, а також їх наслідки називаються поведінкою операції.
Під користувачем даних ми в цій статті розумітимемо програміста, який використовує ці типи даних у своєму коді.
Залишається найважливіше питання: навіщо все це потрібне? Щоб відповісти на нього, розглянемо завдання докладніше.
Уявимо, що у черзі вже є талони з номерами 109, 101, 105, 112 з пріоритетами 5, 3, 1, 1 відповідно. Наступному пацієнту видається талон 113 з пріоритетом 3. Тоді цей талон «обходить» номери 105 і 112, тому що їхній пріоритет нижче, і встає позаду талона 101, з яким їх пріоритети рівні (мал. 1). Коли лікар готовий прийняти наступного пацієнта, то буде викликано пацієнта з номером 109 (мал. 2).
Мал. 1. Новий пацієнт у черзі. Мал.2. Вибір наступного пацієнта у черзі.
Давайте напишемо код, який реалізує цю логіку. Будемо використовувати мову javascript . Спочатку опишемо звичайну чергу, без урахування пріоритету. Створимо клас PriorityQueue. Об’єкти цього класу міститимуть спочатку порожній масив data(створюється в конструкторі). Функція add_elemдодаватиме переданий їй параметр – номер талона – в кінець масиву data, а функція get_nextописуватиме виклик лікарем пацієнта на прийом: повертати значення першого елемента в масиві – номер пацієнта, який встав у чергу раніше за всіх інших, видаляючи з масиву цей елемент, так як , вирушаючи прийом, пацієнт залишає чергу. Також визначимо функцію print_que, яка виводитиме в консоль усі елементи черги по порядку.
Давайте модифікуємо клас, що вийшов, щоб черга враховувала пріоритет елемента. Для цього будемо в масиві dataзберігати не просто переданий елемент, а об’єкт із двома полями: значення ( value) та пріоритет ( priority). У коді такий об’єкт задаватиметься виразом виду var obj = {‘priority’: 1, ‘value’: 112};Перепишемо функцію додавання елемента в чергу:
add_elem(e,p) {
for (var i = this.data.length - 1; i >= 0; i--) {
if(this.data[i].priority >= p){
this.data.splice(i+1,0,{'value':e, 'priority':p});
return;
}
}
this.data.splice(0,0,{'value':e, 'priority':p});
}
Змоделюємо ситуацію, проілюстровану малюнками 1 і 2.
Можлива модифікація: якщо пацієнт перебуває в черзі протягом тривалого часу, наприклад, за цей час лікар уже прийняв як мінімум одного пацієнта з черги, то пріоритет його талона підвищується на 1, проте не може перевищити 8, щоб залишити можливість термінового прийому важких хворих.
Для цього змінимо функцію вибору наступного елемента get_next.
get_next() {
var e = this.data.shift();
for(var i inthis.data){
if(this.data[i].priority<8)
this.data[i].priority++;
}
return e;
}
Можемо помітити, що в даному випадку при вилученні елемента з черги змінюються всі елементи. Це і буде та сама «поведінка операції», про яку йшлося раніше.
Код програми, що вийшов, можна умовно розділити на дві частини: опис класу PriorityQueue і використання цього класу. Зауважимо, що використання класу виглядає досить лаконічно, порівняно з його описом. Працюючи з класом та її функціями програміст, який виступає у разі як користувач класу, може мати уявлення, як саме реалізована логіка роботи всередині функцій класу. Для його роботи достатньо того, що ця логіка відповідає заявленому опису пріоритетної черги. У такому разі кажуть, що клас реалізує певний інтерфейс – набір методів роботи з класом, де зафіксовано вхідні та вихідні параметри. У цьому прикладі це методи add_elem, get_next і print_queue. Можна змінити внутрішню логіку роботи цих методів, якщо цього вимагатиме завдання, як це було у разі підвищення пріоритету при довгому очікуванні. Однак для користувача класу ці зміни не будуть помітними і не вимагатимуть зміни коду основної програми.
Бонус. Що таке структура даних?
У програмуванні також є поняття структури даних, яке певною мірою близьке за змістом типу даних.
У чому різниця? Структура даних – це конкретна програмна реалізація типу даних. Якщо двох людей попросити реалізувати пріоритетну чергу, швидше за все навіть при використанні однієї мови програмування їх реалізації відрізнятимуться, хоча обидві відповідатимуть заявленому інтерфейсу. Тобто вони створять дві різні структури даних.
Структура даних (англ. data structure) — програмна одиниця, що дозволяє зберігати та обробляти безліч однотипних та/або логічно пов’язаних даних у обчислювальній техніці. Для додавання, пошуку, зміни та видалення даних структура даних надає деякий набір функцій, що становлять її інтерфейс.
Висновок
Підіб’ємо підсумки виконаної роботи. Клас PriorityQueueмає такі властивості:
Він може зберігати у собі будь-які елементи з пріоритетом, який задається числом.
Визначено інтерфейс взаємодії з класом: методи add_elem, get_nextі print_queue.
Описані методи реалізують заявлену логіку роботи пріоритетної черги.
Методи мають певну поведінку (див., наприклад, бонус).
Таким чином, ми створили свій абстрактний тип даних та реалізували його мовою javascript . Що ми від цього виграли:
Код основної програми лаконічний і зрозумілий, тому що не містить технічних подробиць внутрішньої роботи черги.
Зручно вносити зміни до логіки роботи черги, не торкаючись основного коду.
Клас PriorityQueueможе бути перевикористаний в інших програмах, де потрібна схожа логіка.
У разі командної роботи можна поділити між людьми роботу над класом та розробку з використанням цього класу. Сполучною ланкою буде інтерфейс класу.
Незважаючи на те, що розробка абстрактного типу даних сама по собі може бути досить трудомісткою, використання АТД здорово допомагає заощадити сили і час при роботі зі складними завданнями. Принцип «розділяй і владарюй» працює тут якнайкраще: створення додаткового рівня абстракції допомагає розробнику розбити складне завдання на дрібніші і простіші, а його колегам спрощує розуміння коду програми, що надзвичайно важливо в командній розробці.
Звичайно, АТД – це не панацея, яка допоможе зробити будь-який код прекрасним, читаним і зрозумілим, уникнувши всіх помилок. Дуже часто навіть досвідчені програмісти у своєму прагненні зробити все правильно та красиво заходять надто далеко в нетрі абстракцій, що навпаки все ускладнює. Коли варто створювати нову абстракцію, а коли це зайве, зрозуміти можна лише з досвідом. Універсального рецепта немає, можна лише порадити намагатися періодично переглядати свій старий код, щоб зробити висновки, що з написаного робить його зрозумілішим, а що через деякий час незрозуміло вже навіть вам самим.
Пам’ятайте, що у висловлювання Девіда Віллера і є і друга, менш відома частина:
У комп’ютерній науці всі проблеми можна вирішити з допомогою додаткового рівня непрямості. Але зазвичай це створює іншу проблему
Більше 40% користувачів засумнівалися у етичному застосуванні ШІ
У споживачів зростає недовіра до ШІ фірм — понад 40% респондентів не вірять, що компанії використовують технологію етично. Про це свідчать результати опитування Salesforce.
У дослідженні взяли участь понад 14 000 споживачів та фірм у 25 країнах.
Майже 70% із них заявили, що в міру розвитку ШІ профільним компаніям варто підвищувати довіру до своєї діяльності.
За даними Salesforce, протягом року респонденти стали менш схильні до використання штучного інтелекту. Якщо у 2022 році понад 80% бізнес-покупців та 65% споживачів були готові використати технологію для покращення якості обслуговування — зараз обидва показники впали до 73% та 51% відповідно.
Окреме опитування майже 1500 австралійців від дослідницької фірми Roy Morgan показало, що близько 60% із них впевнені: ШІ «створює більше проблем, ніж вирішує».
Кожен п’ятий респондент пов’язує із цими розробками причину потенційного зникнення людства до 2043 року.
Дані: Roy Morgan.
Третє дослідження від Pew Research, у якому взяли участь понад 5000 американців, виявив досить низьку поінформованість людей про ChatGPT. Лише 18% із них використали цього чат-бота.
Дані: Pew Research.
На тлі глобальних дебатів щодо необхідності законодавчого регулювання ШІ майже 70% респондентів виступили за введення більшої кількості правил.
Нагадаємо, згідно з опитуванням CFP, третина інвесторів із США довіряють фінансовим рекомендаціям від штучного інтелекту, не звіряючи їх з іншими джерелами.
Раніше LinkedIn вказав на зростання числа професіоналів із навичками роботи в галузі ШІ.
“Реактивність” – це те, як системи реагують на оновлення даних. Існують різні типи реактивності, але в рамках цієї статті реактивність — це коли ми щось робимо у відповідь на зміну даних.
Патерни реактивності є ключовими для веб-розробки
Ми працюємо з великою кількістю JS на сайтах та у веб-додатках, оскільки браузер – це повністю асинхронне середовище. Ми повинні реагувати на дії користувача, взаємодіяти з сервером, надсилати звіти, моніторити продуктивність тощо. Це включає оновлення UI, мережеві запити, зміни навігації та URL в браузері, що робить каскадне оновлення даних ключовим аспектом веб-розробки.
Реактивність зазвичай асоціюється з фреймворками, але можна багато чому навчитися, реалізуючи реактивність на чистому JS. Ми можемо змішувати та грати з цими патернами для кращої обробки оновлення даних.
Вивчення патернів призводить до зменшення кількості коду та підвищення продуктивності веб-застосунків, незалежно від використовуваного фреймворку.
Мені подобається вивчати патерни, оскільки вони застосовні до будь-якої мови та системи. Паттерни можуть комбінуватися для вирішення завдань конкретної програми, часто приводячи до більш продуктивного і підтримуваного коду.
Видавець/передплатник
Видавець/передплатник (Publisher/Subscriber, PubSub) — один із основних патернів реактивності. Виклик події за допомогою publish() дозволяє передплатникам (підписалися на подію за допомогою subscribe()) реагувати на зміну даних:
Кастомні події – нативний браузерний інтерфейс для PubSub
Браузер надає API для виклику та передплати кастомних подій (custom events). Метод dispatchEvent() дозволяє не тільки викликати подію, але й прикріплювати до неї дані:
Ми можемо обмежити область видимості (scope) кастомної події будь-яким вузлом DOM. У наведеному прикладі ми використовували глобальний об’єкт window, який також відомий як глобальна шина подій (event bus).
Наші події викликаються на класі, а не глобально window. Обробники можуть безпосередньо підключатися до цього примірника.
Спостерігач
Паттерн “Спостерігач” (Observer) схожий на PubSub. Він дозволяє підписуватись на суб’єкта (Subject). Для повідомлення передплатників про зміну даних суб’єкт викликає метод notify():
Давайте зробимо наших спостерігачів асинхронними! Це дозволить оновлювати дані та запускати спостерігачів асинхронно:
classAsyncData{
constructor(initialData) {
this.data = initialData
this.subscribers = []
}
subscribe(callback) {
if (typeof callback !== 'function') {
thrownewError('Callback must be a function')
}
this.subscribers.push(callback)
}
asyncset(key, value) {
this.data[key] = value
const updates = this.subscribers.map(async (callback) => {
await callback(key, value)
})
awaitPromise.allSettled(updates)
}
}
const data = new AsyncData({ pizza: 'Pepperoni' })
data.subscribe(async (key, value) => {
awaitnewPromise((resolve) =>setTimeout(resolve, 1000))
console.log(`Updated UI for ${key}: ${value}`)
})
data.subscribe(async (key, value) => {
awaitnewPromise((resolve) =>setTimeout(resolve, 500))
console.log(`Logged change for ${key}: ${value}`)
})
asyncfunctionupdateData() {
await data.set('pizza', 'Supreme')
console.log('All updates complete.')
}
updateData()
/**
через 500 мс
Logged change for pizza: Supreme
через 1000 мс
Updated UI for pizza: Supreme
All updates complete.
*/
Реактивні системи
В основі багатьох популярних бібліотек і фреймворків лежать складні реактивні системи: хуки (Hooks) в React, сигнали (Signals) в SolidJS, сутності (Observables) в Rx.js і т.д. Як правило, їх основним завданням є повторний рендеринг компонентів або фрагментів DOM при зміні даних.
Observables (Rx.js)
Паттерн “Спостерігач” і Observables (що можна умовно перекласти як “сутні, що спостерігаються”) – це не одне і те ж, як може здатися на перший погляд.
Observables дозволяють генерувати (produce) послідовність (sequence) значень протягом часу. Розглянемо простий примітив Observable, що відправляє послідовність значень передплатникам, дозволяючи їм реагувати на значення, що генеруються:
classObservable{
constructor(producer) {
this.producer = producer
}
subscribe(observer) {
if (typeof observer !== 'object' || observer === null) {
thrownewError('Observer must be an object with next, error, and complete methods')
}
if (typeof observer.next !== 'function') {
thrownewError('Observer must have a next method')
}
if (typeof observer.error !== 'function') {
thrownewError('Observer must have an error method')
}
if (typeof observer.complete !== 'function') {
thrownewError('Observer must have a complete method')
}
const unsubscribe = this.producer(observer)
return {
unsubscribe: () => {
if (unsubscribe && typeof unsubscribe === 'function') {
unsubscribe()
}
},
}
}
}
Метод next()надсилає дані спостерігачам. Метод complete()закриває потік даних (stream). Метод error()призначений обробки помилок. subscribe()дозволяє передплатити дані, а unsubscribe()— відписатися від них.
Найпопулярнішими бібліотеками, в яких використовується цей патерн, є Rx.js та MobX .
Наш відеоплеєр має багато налаштувань, які можуть змінюватись у будь-який час для модифікації відтворення відео. Kai з нашої команди розробив значення, що спостерігаються (observable-ish values), що являє собою ще один приклад реактивної системи на чистому JS.
Значення, що спостерігаються – це поєднання PubSub з обчислюваними значеннями (computed values), що дозволяють складати результати декількох видавців.
Приклад повідомлення передплатника про зміну значення:
Передача функції кешує результат як значення. Додаткові аргументи передаються функції. Спостережені сутності, викликані функції, є передплатниками, оновлення цих сутностей призводить до повторного обчислення значення.
Якщо функція повертає проміс, значення надається асинхронно після його вирішення.
Основним недоліком цього підходу є модифікація всього DOM при кожному рендерингу. Такі бібліотеки, як lit-html , дозволяють оновлювати DOM інтелектуальніше, коли оновлюються лише модифіковані частини.
Реактивні атрибути DOM – MutationObserver
Одним із способів забезпечення реактивності DOM є маніпулювання атрибутами HTML-елементів. MutationObserver API дозволяє спостерігати за зміною атрибутів і реагувати на них певним чином:
const mutationCallback = (mutationsList) => {
for (const mutation of mutationsList) {
if (
mutation.type !== 'attributes' ||
mutation.attributeName !== 'pizza-type'
)
returnconsole.log('Old:', mutation.oldValue)
console.log('New:', mutation.target.getAttribute('pizza-type'))
}
}
const observer = new MutationObserver(mutationCallback)
observer.observe(document.getElementById('pizza-store'), { attributes: true })
Прим. пер.: MutationObserverдозволяє спостерігати за зміною не лише атрибутів, але також за зміною тексту цільового елемента та його дочірніх елементів.
Реактивні атрибути у веб-компонентах
Веб-компоненти (Web Components) надають нативний спосіб спостереження за оновленнями атрибутів:
Прим. пер.: Крім MutationObserverі IntersectionObserverіснує ще один нативний спостерігач – ResizeObserver .
Зациклювання анімації – requestAnimationFrame
При розробці ігор, при роботі з Canvas або WebGL анімації часто вимагають запису в буфер і наступного запису результатів у циклі, коли потік рендерингу стає доступним. Зазвичай, ми реалізуємо це за допомогою requestAnimationFrame:
functiondrawStuff() {
// Логіка рендерингу гри чи анімації
}
// Функция обробки анімаціїfunctionanimate() {
drawStuff()
requestAnimationFrame(animate) // Продолжаем вызывать `animate` на каждом кадре рендеринга
}
// Запускаєм анімацію
animate()
Реактивні анімації – Web Animations
Web Animations API дозволяє створювати реактивні гранульовані анімації. Приклад використання цього інтерфейсу для анімації масштабу, положення та кольору елемента:
const el = document.getElementById('animated-element')
// Визначаємо властивості анімаціїconst animation = el.animate(
[
// Ключові кадри (keyframes)
{
transform: 'scale(1)',
backgroundColor: 'blue',
left: '50px',
top: '50px',
},
{
transform: 'scale(1.5)',
backgroundColor: 'red',
left: '200px',
top: '200px',
},
],
{
// Налаштування часу
// Тривалість
duration: 1000,
// Напрямокfill: 'forwards',
},
)
// Встановлюємо швидкість відтворення у значення `0`// для призупинення анімації
animation.playbackRate = 0// Реєструємо оброблювач кліку
el.addEventListener('click', () => {
// Якщо анімацію припинено, відновлюємо їїif (animation.playbackRate === 0) {
animation.playbackRate = 1
} else {
// Якщо анімація відтворюється, змінюємо її напрямок
animation.reverse()
}
})
Реактивність такої анімації полягає в тому, що вона може відтворюватись щодо поточного положення в момент взаємодії (як у разі зміни напряму в наведеному прикладі). Анімації та переходи CSS такого робити не дозволяють.
Реактивний CSS – кастомні властивості та calc
Ми можемо писати реактивний CSS за допомогою кастомних властивостей та calc:
Як бачите, сучасний JS дозволяє досягати реактивності безліччю різних способів. Ми можемо комбінувати ці патерни для реактивного рендерингу, логування, анімації, обробки подій користувача та інших речей, що відбуваються в браузері.
Якщо ви працювали з Angular, то, напевно, зустрічалися з RxJS. Потоки, розлогі конструкції, багато аргументів у методу pipe, а кожен аргумент повертають різні функції з різною кількістю аргументів. Існують інтуїтивно зрозумілі функції типу filter або map. Перший явно фільтрує значення потоці, а другий ці значення змінює. Такі функції називають операторами. І чим глибше ви провалюєтеся в RxJS, тим більше різних операторів ви дізнаєтеся. І з часом дістаєтеся потоків потоків. Тобто замість звичайних значень такий потік емітує інші потоки. Такі потоки називають Higher Order Observables. І для роботи з такими потоками є спеціальні оператори. Можливо, ви чули, що такі оператори називають Higher Order Operators (HOO). Вони можуть вирівнювати потоки або, іншими словами, робити їх звичайним.
У цій статті я покажу, що в HOO немає нічого міфічного, і розповім, у яких випадках вам потрібно використовувати оператори вищого порядку. Зараз ви подумаєте, що це нудний лонгрід, але не поспішайте. Ми розглянемо всього 4 оператори: switchMap, exhaustMap, concatMapі mergeMap.
switchMap
switchMapОднозначно найпопулярніший з усіх. Але чому? А з однієї просто причини — цей оператор позбавляє нас від стану гонки, що дуже часто зустрічається.
У цьому коді ми знаходимо input, з яким взаємодіє користувач і підписуємось на подію input. Тобто потік search$ емітит рядка. Усередині підписки бачимо, що у кожен еміт рядка відправляється запит на сервер і відповідь сервісу виводиться у консоль.
У цьому коді можна побачити щонайменше дві проблеми:
Race state. Зазвичай при пошуку чогось користувача важливо бачити результат саме останнього запиту. Але код такого виду не дає нам гарантії, що останні дані, виведені в консоль, відповідають останньому рядку, що випускається в потоці search$.
Subscribe in subscribe та жодного unsubscribe. Є дуже хороше правило, за яким можна позбавити себе багатьох проблем, — на кожен subscrib має бути unsubscribe. Це щонайменше знизить ймовірність витоку пам’яті.
Але давайте подумаємо, як має працювати пошук:
У момент еміту рядка перевірити наявність активних запитів
switchMapгарантує нам, що ми завжди будемо отримувати результати останнього потоку та позбавляє нас race state. Ну і приємний бонус полягатиме в тому, що відмовившись від зовнішньої підписки автоматично відбудеться і відписка від внутрішньої. Профіт!
Резюмуємо. switchMapможна використовувати у випадках, коли нам важливим є результат останньої дії, наприклад, при пошуку або реалізації нескінченного скрола. Якщо всі попередні дії можуть не враховуватися, можна сміливо брати switchMap.
exhaustMap
exhaustMapОднозначно найпопулярніший з усіх. Причина мені не до кінця зрозуміла, але за допомогою нього можна реалізувати пошук, але використовуючи інший підхід.
Як і в першому випадку нам знадобилася ще одна змінна поза потоком. Це додає коду складності і якщо ми захочемо змінити поведінку потоку, все доведеться переписати. Ну і як ви вже здогадалися на допомогу нам приходить exhaustMap.
Резюмуємо. exhaustMapпотрібно використовувати у випадках, коли при активній підписці на потік інші можна ігнорувати, як у разі пошуку натискання кнопки або, наприклад, при пропуску подій початку анімації при її відтворенні.
mergeMap
mergeMap– Оператор, який об’єднує всі внутрішні потоки в один вихідний потік. Це означає, що внутрішні потоки можуть завершуватись у будь-якому порядку, і їх результати будуть об’єднані разом. І це найпростіше пояснення, яке я зміг із себе видавити.
У цьому коді ми бачимо entityId$ – це потік рядків з id певної сутності. Тут ми повинні на кожен id запросити дані щодо сутності з сервера і додати або оновити цю сутність в стор. Власне, саме це наш код і робить і вирішувати тут нема чого. Але проблеми є і в цьому випадку вони абсолютно ідентичні попереднім. Давайте спробуємо ускладнити завдання і ввести обмеження в 3 запити одночасно.
Я навіть не намагався перевіряти код на працездатність, бо написав його у редакторі тексту. Код став складно-читаним. Функція processNextмає кілька побічних ефектів усередині. А ще є додаткові змінні за межами потоку та функції. Скласти все це воєдино досить складно.
Саме такі завдання вирішує mergeMap. Давайте перепишемо перший приклад із використанням цього оператора:
У цьому коді mergeMapпідписується на кожен потік, повернутий entityService.get(id)і їх значення видає в одному єдиному потоці.
Добре, а як бути з обмеженням 3 запити в один момент часу? Виявляється, що mergeMapвже й так усе вміє. Другий аргумент у mergeMapприймає число, яке якраз налаштовує конкурентність.
Резюмуємо. mergeMapвідмінно підходить, коли ви хочете виконувати паралельні дії та поєднувати їх результати. Однак, слід бути обережним, оскільки може виникнути багато активних запитів, якщо вихідний потік випромінює значення занадто швидко.
concatMap
concatMap– Останній оператор вищого порядку. Ключова відмінність полягає в тому, що concatMap підтримує порядок виконання. Він дочекається завершення одного внутрішнього потоку, перш ніж перейде до наступного.
Щоб практично подивитися на його використання, ми можемо взяти попередній приклад і змінити до нього вимоги. Так вийшло, що нас перестало влаштовувати невпорядкованість запитів, і ми хочемо виконувати їх не паралельно, а по черзі. Тобто конкурентність має стати рівною одиниці.
Але mergeMap з конкурентністю 1 робить те ж саме, що і concatMap! Буквально. Це чудово видно у вихідному коді оператора.
Тобто використання mergeMap із конкурентністю 1 на стільки частий кейс, що його винесли в окремий оператор.
Резюмуємо. concatMapчудово підходить для ситуацій, коли порядок виконання важливий. Якщо ви хочете обробити послідовність дій без паралельної обробки, це ваш вибір.
Висновок
Високовирівневі оператори є потужним інструментом в арсеналі кожного розробника, що працює з реактивним програмуванням. Вони надають гнучкість і елегантність при обробці складних даних і дозволяють скоротити код, роблячи його більш читаним і підтримуваним.
Оператор switchMap чудово підходить, коли нам важливий лише останній результат випромінювання, наприклад, у разі пошуку у реальному часі.
exhaustMap ідеальний для випадків, коли нам потрібно ігнорувати нові об’єкти, що спостерігаються, до завершення поточного.
mergeMap дозволяє обробляти кілька вхідних об’єктів, що спостерігаються паралельно, але може призвести до перевантаження, якщо не контролювати кількість одночасних потоків.
concatMap гарантує порядок обробки, виконуючи кожен внутрішній об’єкт, що спостерігається послідовно.
При правильному використанні ці оператори можуть справлятися з безліччю реактивних завдань, будь то події з інтерфейсу користувача, HTTP-запити або навіть складні анімаційні послідовності.
Однак ключове слово тут – правильне використання . Завжди аналізуйте вимоги вашої програми та ретельно вибирайте відповідний оператор. Це допоможе уникнути небажаних побічних ефектів та створити реактивні рішення, які можуть масштабуватися та легко підтримуватися.
Реактивне програмування пропонує безліч інструментів, серед них високорівневі оператори займають особливе місце. Провівши час на вивчення та розуміння їх особливостей, ви значно можете покращити якість та ефективність вашого коду.
Третина інвесторів у США заявила про довіру фінансовим радам ШІ
Близько 31% інвесторів із США довіряють фінансовим рекомендаціям від штучного інтелекту (ШІ), не звіряючи їх з іншими джерелами. Про це свідчить опитування CFP .
Близько третини із 1153 респондентів фактично отримували поради щодо планування бюджету від нейромереж, при цьому 80% з них відзначили високий рівень задоволеності цим досвідом.
Більше половини опитаних зазначають, що їм все ж таки зручніше користуватися підказками, створеними ШІ та в соціальних мережах, якщо вони перевірені експертами. 52% відзначили бажання скористатися порадами від роботів у майбутньому.
«За останнє десятиліття кількість неперевірених інвестиційних рекомендацій на таких платформах, як TikTok та Instagram різко зросла. Інвестори мають бути обережними з порадами “фінансистів” на цих платформах. Поява інструментів штучного інтелекту, таких як ChatGPT та Bard, ще більше ускладнила перевірку інформації», – зазначив глава CFP Кевін Келлер.
Близько 50% респондентів вірять, що незабаром ШІ зможе доповнити послуги традиційних консультантів. Ще 11% вірять, що нейромережі повністю замінять їх.
Раніше опитування серед керівників служб управління корпоративними ризиками показало, що 66% менеджерів вважають генеративну ШІ загрозою для організацій.
Нагадаємо, за даними дослідження Quartz , штучний інтелект на 15% успішніше справляється з проходженням CAPTCHA, ніж живі люди.