Pull to refresh

Comments 41

Да, конечно, я отредактирую статью и добавлю в нее не только ссылки на видео, но и слайды, ссылки на примеры кода в starter kit, манифест методологии Metaserverless.

Простите, но мне кажется что вы преувеличиваете. Node.js не считается платформой для малограмотных, и не могу понять откуда вывод о том что в него слабо проникают фундаментальные знания.
Особенно удивили временные рамки — 2012-2015 год это начало развития node.js.
Сложно представить что найдётся серьёзный продукт код которого не адаптировался.

Вы послушали 1 часть? Я же там все объясняю. Люди используют фреймворки и не догадываются о том, что они концептуально остались в самом начале развития ноды. Меня часто зовут сделать аудит и ревью продуктов, так вот я вам скажу, что серьезные продукты не используют и почти ничего из появившегося после 6.x и не задумываются про множество давно известных и решенных проблем. Люди даже не слышали про асинхронные стектрейсы, про worker_threads, про модули vm и v8 в которые проблошено много API из v8, про класс fs.Dir, про await events.once, про то, что for await блокирует ивентлуп и я еще могу на 2 страницы тут перечислять, это просто примеры.
Я в принципе согласен. Большинство тех разработчиков которых знаю и с которыми работаю и не слышали про SOLID. Большинство просто херачит код не парясь о каких-то там паттернах т.д.

Многие пишут не понимая даже что такое процесс, треды и общая память, и чем это светит например в тестах. Ну да ладно… Но у меня есть одна маленькая победа — все таки я смог донести до большинства в компании зачем нужен Dependency Injection =))

И хоть сам копаюсь в ноде довольно глубоко, даже с libuv играюсь в XCode, можно подробнее о «await блокирует event-loop»? Это же вроде просто сахар к промисам. И если операция асинхронная, то await отработает так же как и промис. Или вы о том когда разработчик делает async/await на синхронную функцию и ожидает что функция волшебным образом станет асинхронной?
Я писал про цикл for await, люди начинают итерироваться по большому массиву, думая, что это же асинхронный цикл и он их спасет, отдавая управление между итерациями, но этого не происходит, нужно массив обернуть, потому, что интерфейс AsyncIterable позволяет отдавать управление, но его реализация на массивах, сетах и мапах не поддерживает этого. Тут отдельная лекция: youtu.be/wYA2cIRYLoA
Понятно. Нам еще не завезли =))
Вот переедем на десятую ноду, сколько новых способов будет выстрелить себе в ногу… ну или голову =)

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

Не хочу обидеть, но лекция больше похожа на объяснение методом научного тыка. Что не есть плохо, я тоже люблю как говорится «почувствовать». Но мне кажется что лекция не доносит почему так происходит. Мне вот этот чувак очень помог — blog.insiderattack.net/event-loop-and-the-big-picture-nodejs-event-loop-part-1-1cb67a182810

И тогда все очень логично получается, и понятно почему промисы а блокируют. Потому что так libuv написан. Никакой магии.

З.Ы.
По моему то что вы там реализовали можно сделать при помощи setImmediate
Это вообще лекция не про промисы, у меня есть отдельно лекции и про ивентлуп и про промисы и про async/await, где я все это рассказываю, о чем вы говорите. Но именно эта лекция о применении контракта Async Iterable и цикле for..await, при чем, про Async Iterable у меня есть еще отдельная лекция: youtu.be/rBGFlWpVpGs я не понимаю, к чему тут setImmediate, а промисы являются только частью контракта Async Iterable. И все эти лекции часть большого курса: habr.com/ru/post/452974 в котором есть и теория и много вот таких конкретных применений.

Посмотрел видео: очень сложно и навороченено. Почему не сделают как в C#:


  • функция возвращает Task
  • при вызове её через await она автоматом запускается в отдельном потоке.

Почему в JS нельзя так сделать?!

Потому что C# так, как вы написали, не работает.


при вызове её через await она автоматом запускается в отдельном потоке

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


Вообще, в C# асинхронность работает почти так же, как и в Javascript. Единственная разница — в том, что очереди событий другие, и "разбирать" их могут несколько потоков одновременно. А, ну ещё некоторые продолжения выполняются синхронно.

Другая природа языка, потоки есть, worker_threads в ноде и workerы есть в браузере, но у них другой смысл и применять их как потоки в Java, C++ и C# не выйдет. В JS все на асинхронном программировании, это дико сложнее, но дает преимущество в утилизации ресурсов. Асинхронно можно писать системный код, но вот бизнес-логику нужно писать в псевдо-синхронном стиле, на async/await.

Имею дело с легаси каждый день, и как-то так выходит, что исправлять баги в проектах, написанных не "фанатами" SOLID значительно проще.

Ну фанатизм никогда не помогал, но вот понимание разницы между coupling и cohesion, а так же следование принципу information expert и закону Деметры, только улучшает код. Ухудшение скорее происходит после того, что люди GoF выучили и лепят бездумно паттерны, оверинженерят как только могут.
А можете пожалуйста объяснить для чего нужен DI в Node.js?
Мы отказались от него в пользу модулей, которые сами по себе являются контейнерами, и для тестов используем jest моки.
Из-за этого из конструкторов и логики классов удалилось множество лишних вещей и сильно упростился код и типизация в TypeScript.
Ну во первых — это красиво… шучу. Мы от джеста отказались в силу того что слишком много магии. Кроме того, даже он иногда не справлялся с тем ужасом который у нас в коде.

Мое мнение такое, что жест и други кастыли в виде rewire или proxyquire появились именно потому что код писали криво, а тестировать то хоть как-то хотелось. Мы в большом проекте говна нахавались, когда тесты падали тупо после изменений имени файла, порядка выполнения или количества кейсов. Потому что люди волшебными тулзами то мокали, то где то забывали, а память то общая… потом сиди 2 дня дебаж что бы понять где забыли вернуть состояние.

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

А также это помогает избежать очень неприятных багов в виде cycle dependency. Да и с синглтонами тоже жизнь та еще…

Да, согласен, DI без статики то еще удовольствие. Зато в тестах никакой магии. Часто даже к sinon обращаться не надо. Дактайпинг во всей красе.

Опять же, без фанатизма. Инжектить не значит что щас мы lodash будем пробрасывать. Но вот DAO, Repository, http, queue, db и т.д. инжектим.

Ну еще из плюсов, легче собирать из этих кубиков нужный функционал. А когда все друг другу require делают, система превращается в Big ball of mud.

Так же легче перетаскивать отдельный компоненты например в отдельный сервис.

У вас может быть другой опыт и мнение. Не претендую на истину, но вот вот как-то так…

З.Ы.
Хочу заметить речь не идет о DI фреймворках… их я тоже не очень люблю. Не люблю магию и implicitly. Но на вкус и цвет…
Во вчерашнем 2м вебинаре (ссылку в статью добавил) я рассказываю, как могут передаваться ссылки между модулями: через глобал, через require (dependency locator), DI, через ивенты могут приходить, через аггрегацию и ассоцияию классов (передача ссылок в конструкторы и примешивание), через vm.createContext и другие способы. Нельзя сказать что какой-то из них плох, а какой-то хорош просто сам по себе, есть разные случаи применения. И важно понимать, не просто, что global = плохо, а почему именно. Потому, что можно те же проблемы и через require и через события даже сделать. Более того, можно через глобал передавать и не сделать проблем… внезапно. Начинать понимать это нужно с GRASP, закона Деметры, и принципа инверсии зависимостей из SOLID. Посмотрите, там интересно.
А про платформу для малограмотных, Вы поговорите с программистами на Java, C#, C++, они все Вам расскажут, что они думают про node.js, да, обидно, но они же и факты приводят. Например, что мидлвары это кривая и косая реализация паттерна Chain of responsibility и если о нем почитать, то оказывается, что куча проблем с порядком исполнения мидлваров можно было бы избежать, если бы разработчики фреймворков читали книги по ООП и архитектуре.
Они говорят так про ноду как платформу или про говнокод во фреймворках типа express?
Они не различают, за фреймворками платформу слабо видно. Ведь разработчики слабо знают платформу, но готовы бесконечно спорить, чей фреймворк лучше, и в общем, нодовское сообщество производит не лучшее впечатление на представителей других технологий.
Это справедливо. Взрощенных на корпоративных тулах можно понять. Однако, камешек в огород гуру тоже найдется, нода может и сама работать и без фреймворков и никто не заставляет пользоваться трудами рук в куркуме. О ноде я вообще узнал когда увидел ее в папке исталяции adobe photoshop и где там малограмотность…
Я когда разбирался с сообществом увидел попытки натянуть предыдущий опыт разрабов на ноду, аля lavarel и общее непонимание ситуации технологий и неразбериху. А вот переосмысления предыдущего опыта фреймворков всех этих куч hapi, restify, koa и какая то экосистема мне встретилась только в Fastify. (10 нода минималка) Макаронникам я бы тоже не шибко доверял, маловато там народу по мне, но как-то там более менее все похоже на продукт и он продолжает развиваться.
Но я уверен, что есть компании, у которых грамотно на ноде написано, например, NearForm и Paypal, но даже у Amazon и Google в доках по использованию ноды для FaaS сплошной говнокод.

А вы не думали что мнение что JS для малограмотных это не просто устаревший стереотип? Может действительно программисты на других языках знают то что не знают JS-ники?


Я веб оставил после того как посмотрел сколько срани попадает в node_modules в проекте уровня hello world.


Может это показатель плохой продуманности языка и тулчейна?

UFO just landed and posted this here
Ну вот 21 апреля я покажу стартер кит для ноды размером 15-20кб, и почти без зависимостей (опционально eslint, pg, ws) и умеющий больше, чем стартер киты на 500-800мб зависимостей, которые так распространены в сообществе. Его уже можно посмотреть тут: github.com/HowProgrammingWorks/NodejsStarterKit
UFO just landed and posted this here
UFO just landed and posted this here
Но ведь если не писать «свои велосипеды» откуда возьмется «чужой код»?
Этот стартер кит показывает, что можно взять 500мб зависимостей, а можно написать 15кб. Что находится в этих 500мб и действительно ли там все тестами покрыто и хорошо поддерживается, у меня вот сомнения. А 15кб это очень мало, их можно посмотреть и понять, их даже поддерживать можно. Ну и я эти 15кб покрою тестами и можете их переиспользовать, как Вы любите. Возможно, я допишу еще кое-что и там будет 20кб, но не 500мб.
UFO just landed and posted this here
Когда стектрейс работал только для синхронного кода, т.е. в основном мог использоваться в юниттестах, да и то не во всех, а нода же это сплошной I/O, и понять, что происходит по логам со стектрейсами из реальной системы было очень тяжко. А так, люди не все даже понимают, что такое стек трейс и читать их не умеют, все больше озабочены вопросами типа, что лучше экспрес или коа.
UFO just landed and posted this here
Сам цикл for..in, который не гарантирует порядок индексов для массивов

Пардон, а зачем вы используете for..in для итерации массивов? о_О

UFO just landed and posted this here

В таком случае непонятно почему вы относите это к "в JS переусложнена куча банальных вещей". for-in это просто очень старый механизм перебора ключей по объекту, включая его прототипы. Очень низкоуровневая по сути штука (в пределах JS, разумеется). Его просто нет резона тащить в код почти… всегда. Потому что это очень необычная задача, когда вам надо пролистать все ключи включая прототипные, да ещё и с особенностями из defineProperty.


В JS есть итераторы и цикл for-of. И я не уверен что его можно назвать переусложнённым. Он вроде простой как валенок.

Да, почти всегда имеет смысл брать Okject.keys, а лучше Object.getOwnPropertyNames и потом for..of
UFO just landed and posted this here
Почитаю, интересно. Но нода до версии 10.13.0 уже не поддерживается, там за это время сотни дыр найдено и залатано. Я уже не говорю, что там по безопасности с пакетами, которые прибиты гвоздями к 4.x или 6.x. Тут 2 месяца подождать и современные пакеты на npm audit выдают пару экранов проблем. Ну в принципе, я знаю людей, у которых не LTSные версии 5, 7, 9 в продакшене и даже до сих пор 0.12 живет.
UFO just landed and posted this here

А что, если не секрет, вы такое пишете, что вам имеет смысл писать for-in в целях производительности? И если вам критична производительность аж на таком уровне, то вероятно for-of вам там противопоказан ввиду того, что итераторы вовсе не невесомые.

UFO just landed and posted this here
Sign up to leave a comment.

Articles

Change theme settings