#worth_seeing
Цього тижня з консалтингу був цікавий баг. Проблему ілюструє такий код:
import { scheduler } from 'node:timers/promises';async function countLikes() { const postIds = [1, 2, 3]; let likes = 0; await Promise.all( postIds.map(async (id) => { likes += await fetchLikes(id); }) ); return likes;}async function fetchLikes(id: number) { await scheduler.wait(Math.random() * 1000); return id;}Очікуваний результат виконання функції countLikes це 6, але в коді є Race Condition. Щоб його виправити необхідно замінити
likes += await fetchLikes(id) наconst count = await fetchLikes(id);likes += count;Щоб уникати таких випадків існує eslint правило require-atomic-updates. Воно за замовчуванням вимкнено у
eslint:recommended . Як правило воно надто суворе, оскільки змушує писати код у Defensive programming style. Особисто мені це не зручно, тому я тримаю його вимкненим, але час від часу вмикаю його, щоб переглянути ризиковані місця.Академічно правильний спосіб боротьби з Race Conditions є у доповіді Тимура Шемседінова Web Locks API in Node.js and browser.