JavaScript как мыслевирус

    Вообще я стараюсь не писать статьи и комментарии не на технические темы, но коль скоро появились не совсем технические по духу статьи JavaScript как явление и JavaScript как праздник, я счел нужным принять участие в дискуссии.

    Начнем с того, что я не пишу на JavaScript профессионально. Я много пишу на TypeScript, считаю что разбираюсь во frontend-разработке (например сейчас я занимаюсь интеграцией собственной реализации VDOM в свой датагрид-движок Lattice, о котором скоро будет отдельная статья. Ну как скоро… будет, в общем :), однако мой основной профиль — C# и делать всё, чтобы защитить бедных C# разработчиков от излишнего ныряния в JavaScript.

    Так вот. Прошу обратить внимание, что я решительно не имею ничего против JavaScript как такового и его технической экосистемы. Это нормальный язык, с приемлемым тулсетом. Во всяком случае мне в нем комфортнее чем в каком-нибудь… LabView. Я не считаю его уж шибко плохо сделанным — в конце концов в нем нет несовместимых с жизнью недостатков, но однако и ничего революционного или магического я в нем так же не нахожу. Мой основной посыл — к сообществу. К людям, а не к технологии, ибо как с моей точки зрения, большинство проблем и холиваров вокруг JavaScript происходит не от самого языка, а от его, как мне иногда кажется, обезумевших последователей. Имея за плечами продолжительный опыт общения с разработчиками на JavaScript, я предположил что этот язык работает как мыслевирус, который со временем превращает пишущего на нем человека в агрессивного фанатика, чего мне не удалось отметить с другими технологиями. Собственно, эта статья является сатирой на штампы JavaScript-разработчиков, которых JavaScript поразил как мыслевирус. Отсюда и название.

    И да. Я не считаю что все поголовно JavaScript-разработчики такие. Среди них много нормальных и адекватных людей, которым удалось (или не удалось :) остановиться на каком-либо квалификационном уровне и сохранить трезвость ума и здравость памяти. Честь им и хвала. Однако же, фанатики от JavaScript-а по своей природе — гораздо более «громкие» (так всегда: кто-то кричит, а кто-то работой занимается) и настолько фееричны, что заслуживают отдельного рассмотрения. Так же в статье будет упоминаться jQuery. Так вот — я ни в коем случае не агитирую писать всё на нём и не использовать более продвинутые решения. Используйте то, что нравится, но пожалуйста, оставайтесь при этом людьми. Итак…

    Дорогой JavaScript-разработчик!


    Если ты это читаешь, то ты должен знать: твой язык имеет характер мыслевируса. Он серьезно разъедает мозг по мере того, как ты продолжаешь заниматься этой гадостью. Сам ты этого, вероятно, не замечаешь, но мы, люди «извне», слышим тебя, видим и читаем. Мы разработали специальную карту с советами что делать, чтобы ты мог самостоятельно диагностировать тяжесть своего состояния, вылечиться и по-скорее вернуться к нормальной жизни.

    0 уровень: «jQuery — хороший»


    Симптомы:

    — JavaScript тебя интересует только по работе;
    — Ты можешь написать кусок кода в теге <script>;
    — У тебя нет особого желания говорить о JavaScript, кроме как иногда жаловаться на него коллегам в курилке. Ты вообще его и за язык-то не считаешь;
    — jQuery — удобный инструмент и искренне тебе помогает в делах;
    — JavaScript написан в резюме одной строчкой наряду с Java, C/C++ и SQL.

    Диагноз:

    Здоров. У тебя все хорошо, мозг не задет, проблем не наблюдается. Скачай сериал и открой пиво — ты хорошо поработал на этой неделе.

    1 уровень: «Я просто сижу там, где JavaScript-ят»


    Симптомы:

    — Тебя забавят замыкания в JavaScript, ты испытываешь легкую гордость от того, что понимаешь как они работают;
    — Ты раскладываешь JavaScript-код по файлам, поскачивал кучу плагинов к jQuery, думаешь об изучении AngularJS и чувствуешь успокоение и расслабление;
    — Читаешь мануалы по плагинам, в соседней вкладке браузера у тебя обычно порнушка;
    — jQuery — рулит и педалит, AngularJS отдается в голове звуками таинственного Туманного Альбиона;
    — Ты знаешь о том, что '3' — 2 == 1, но '3' + 2 == '32' и это вызывает у тебя негодование.

    Диагноз:

    Все по-прежнему в порядке, но хитрый вирус JavaScript летает повсюду в воздухе. Береги себя и носи защитную маску.

    2 уровень: «Я могу бросить когда захочу»


    Симптомы:

    — Ты разбираешься в прототипном наследовании. Тебе немного мерзко, но в целом терпимо;
    — AngularJS внедрен в домашний проект. Ты говришь начальнику что неплохо бы и в рабочем использовать;
    — Читаешь мануалы по AngularJS, попутно изучаешь TypeScript/CoffeeScript. Изредка с интересом почитываешь рекламные статьи, рассказывающие о магии JavaScript и о том, как некая компания X с ним счастливо живет;
    — jQuery тебя больше не заводит. Ты начинаешь использовать термины «MVW», «DSL», «DOM-дерево». JavaScript-объект называешь только «хэш»;
    — Видео навроде JavaScript WAT больше не вызывают бурных эмоций. Ты понимаешь как это работает и почему.

    Диагноз:

    Началось! Ты этого не замечаешь, но твой мозг уже атакован! Ради всего святого, научись жить с этим. Научись контролировать это. Не давай ему тебя поработить — и тогда все будет нормально.

    Здесь ты начал использовать npm



    3 уровень: «Не вижу в этом ничего плохого»


    Симптомы:

    — AngularJS в продакшене твоего рабочего проекта. Не на всех страницах, но хоть так;
    — Ты осознаешь что фронтенд — целая отдельная часть системы и невозможно же её поддерживать силами backend-разработчиков. Говоришь об этом с начальником, получаешь недоумевающий взгляд;
    — Пишешь на TypeScript и нервно думаешь как бы автоматизировать сборку фронтеда. Читаешь статьи про grunt. Плотно знакомишься с опытом использования JavaScript в модных стартапах;
    — Коллеги, в основном совмещающие backend с допиливанием скриптов на страницы проекта, перестают понимать что ты говоришь и назначают тебя ответственным за все, что касается клиентской части. Из-за этого у тебя появляется легкое негодование и небольшая обида на них;
    — В резюме ты стираешь пункт JavaScript, и добавляешь новую секцию: Frontend.

    Диагноз:

    Твоя болезнь прогрессирует. Ты этого, скорее всего, не замечаешь, но просто поверь мне — вирус уже обосновался в твоей голове. Отложи JavaScript, попиши на C, освой какой-нибудь игровой движок. Тебе срочно необходимо отогнать от себя мысли о JavaScript, чтобы сдержать развитие болезни. На этой стадии еще можно взять себя в руки и быть просто хорошим fullstack-инженером.

    4 уровень: «Вы просто не понимаете сути»


    Симптомы:

    — Сильное желание говорить о JavaScript. В курилке ты с горящими глазами рассказываешь недоумевающим коллегам о том, что JavaScript можно запускать вне браузера. Обижаешься, когда они не считают это серьезным достижением;
    — Фронтенд рабочего проекта собирается отдельно, с использованием grunt и require.js. От этого тебе делается хорошо и приятно, появляется ощущение тепла и домашнего уюта. Коллеги не понимают что там происходит и почему именно так. На все вопросы отмахиваешься и отвечаешь нечто вроде «да там долго объяснять». Очень злишься, когда коллеги пишут что-либо в теге script;
    — TypeScript становится тебе тесноват;
    — Читаешь много концептуальных статей про будущее JavaScript. Узнаешь о существовании React, пробуешь его на домашнем проекте. Получаешь первый писательский опыт в комментариях к статье о React, находишь там поддержку и понимание;
    — Подумываешь съездить на конференцию по JavaScript — встретиться с единомышленниками.

    Диагноз:

    Разжижение мозга в самом разгаре. Вирус самодовольно откусывает кусочки серого вещества и со смаком и хрустом пережевывает. Просто остановись, съезди в отпуск — желательно на Гоа, года на 2, научись медитации. Если ты не научишься контролировать свой JavaScript, то он убьет тебя и разрушит твою жизнь.

    5 уровень: «JavaScript — няшка. А вы все — быдло»


    Симптомы:

    — Пробуешь React на домашнем проекте. Полоскаешь мозги начальнику, что весь ваш сайт надо срочно переделать на SPA и изоморфный рендеринг. Закономерно получаешь предупреждение о скором увольнении, но гордо хмыкнув увольняешься сам и уходишь в хипстерский стартап;
    — TypeScript тебя сильно ограничивает в возможностях. Отказываешься от него не новом месте работы в пользу pure js;
    — Любого, кто напишет тебе про '3' + 2 незамедлительно называешь безграмотным быдлом, которое просто не может осилить язык. Для тебя это уже очевидно. Начинаешь считать, что любой человек, у которого JavaScript не является основным языком работы — просто органически не способен понять прототипное наследование. Это — для избранных;
    — Едешь на конференцию по JavaScript. Там тебе впервые показывают как за 20 секунд сделать сервер на Node.JS. Восторгаешься. Вирус, подпитавшись материалами с конференции откусывает ту часть мозга, которая еще помнила про многопоточность. Она помирает и не успевает задать свои вопросы;
    — Считаешь что VDOM — неочевидное и гениальное решение, которое может прийти только в самые светлые головы этого мира.

    Диагноз:

    Болезнь подходит к необратимой стадии. Посмотри — вирус уже рушит твою жизнь. Немедленно достань учебник по C++ и выполни десяток-другой задач. С тобой становится невозможно общаться! Ты агрессивен и съехал с катушек. Я знаю, что ты в это не веришь, но окружающие всё видят.

    Ты начал использовать Node.JS



    6 уровень: «Это полноценный технический стек!»


    Симптомы:

    — Считаешь что весь web скоро перейдет на изоморфный рендеринг. Классические подходы устарели, а лично ты — стоишь на пороге технологической революции. Меняешь в резюме заголовок на «JavaScript-профессионал»;
    — Раз за разом запускаешь сервер на Node.JS. Проверяешь его на самых разных задачах — блог, аналог твиттера, todo-лист, хостинг картинок. Поражаешься быстродействию. Считаешь что это и есть The Web Development;
    — Любой эксперимент начинаешь с установки webpack-а, react-а и еще десятка пакетов. В процессе скачивания зачарованно смотришь на монитор;
    — Забываешь зачем нужны SQL-базы. Искренне не понимаешь почему на mongodb нельзя делать вообще все. Авторов видео mongodb is web scale считаешь неграмотными толстыми троллями;
    — Асинхронные операции в Node.JS для тебя — cutting edge. Ты полностью уверен, что ни в одном другом языке кроме как JavaScript это невозможно и никаким другим фреймворком кроме Node.JS это не поддерживается.

    Диагноз:

    Сильное повреждение головы. Картина мира капитально нарушена. Ну вот, это случилось. Мы тебя предупреждали. Сейчас с тобой уже невозможно дискутировать — просто поверь на слово, что надо остановиться. Перестань этим заниматься и поступи снова в университет. Просто поверь — так будет лучше.

    7 уровень: «Мир должен знать!»


    Симптомы:

    — Пишешь свою первую статью об успешном внедрении Node.JS для решения, как тебе кажется, очень важных задач в вашей компании. В комментариях грубишь всем, кто посмеет усомниться в твоем успехе;
    — Наотрез отказываешься слушать про другие языки и фреймворки. Предпочитаешь узнавать о них из разговоров с друзьями. Уверен, что C++ устарел и скоро его перестанут использовать. Java/C#/VB — это enterprise-языки и в них нет ничего кроме бессмысленного нагромождения паттернов, а работают они медленно потому что в них нет асинхронных операций. Вместо любых аргументов, что это не так — слышишь белый шум;
    — JavaScript уже давно для тебя идеален. В нем нет недостатков, а если кто-то считает, что они есть — то только потому что этот кто-то не может открыть документацию и почитать, о чем ты ему незамедлительно сообщаешь;
    — Социальная активность возвращается. Правда, ты не общаешься ни с кем, кто не входит в JavaScript-тусовку. Любого, кто задает тебе вопрос по JavaScript снисходительным тоном отправляешь «читать книжки» и упрекаешь в непонимании очевидного;
    — Ты стал писать меньше кода. В основном ты проводишь время в чтении статей, расхваливающих JavaScript и пишешь одобрительные комментарии под ними. Называешь это «обмен экспертными мнениями» и «узкоспециальной профессиональной дискуссией».

    Диагноз:

    Критическое поражение мозга вирусом. Задеты важные мыслительные центры. Собери жесткие диски со всех компьютеров и выброси. Устройся работать грузчиком. Просто таскай коробки, пей, и ни с кем не разговаривай. Выброси свой Google Nexus и купи старенькую черно-белую нокию. Через несколько лет сможешь вернуться в программирование, начав изучение с С++. Не задавай вопросов — так надо.

    8 уровень: «Вся индустрия только и была создана для JavaScript»


    Симптомы:

    — Для тебя в JavaScript-е лучшие пакетные менеджеры. Ты абсолютно уверен, что системы должны собираться из как можно более мелких пакетов по 10 строчек, а любая модульная декомпозиция строится по принципу «меньше модуль — значит лучше»;
    — Считаешь что статическая сильная типизация — это тупиковая ветвь развития. Все более-менее типизированные языки скоро вымрут из-за своей негибкости и перегруженности. Ничего не должно ограничивать настоящего программиста — в том числе и система типов. Наследование, интерфейсы, абстрактные классы — пережиток прошлого, которые только все усложняют;
    — … а JavaScript — вообще единственный язык, который избавляет человека от таких условностей. Он стоит на первых местах во всех рейтингах индустрии, развивается семимильными шагами и ничего кроме него не жизнеспособно. Ну может разве что TypeScript. И тот нужен только тем болезным, которые не осилили pure js;
    — Ты забыл слово «многопоточность». Считаешь что это что-то уровня ассемблера и тебе это знать не нужно, ведь Node.JS полностью тебя от этого абстрагирует. Ты уверен что так и должно быть, а люди, которые в этом разбираются — или носители ненужной и бесполезной информации, или разрабатывают операционные системы;
    — Ты чувствуешь, что вся IT-индустрия развивалась как-то неправильно. В ней много неуместных усложнений, которые никому не нужны. Ты искренне уверен, что все должно быть гораздо проще и что все люди, которые разрабатывали теоретическую базу для программирования — очень глупые, раз этого не понимали. И за что им только докторских степеней пораздавали? Ты бы справился гораздо лучше.

    Диагноз:

    Вирус целиком съел твой мозг и заменил его. Сожалеем, но тебя уже не спасти.
    Метки:
    Поделиться публикацией
    Комментарии 626
    • +20
      Понимаю, что автор статьи подошел с юмором :)

      А теперь по сути, из личного опыта так сказать. Был свидетелем, когда в JS приходили люди из мира Java. Первое, что я слышал — «да ваш JS га… о. Нет типов? Да это убожество! А это еще и работает?». Первое что приходило в голову тогда — «дааа… походу люди какие-то фанатики Java и ничего другого не видят и видеть не хотят».

      Т.е люди приходят в JS, считают, что JS это что-то типа для формочек в браузере. Не разбираются, как что работает, не вникают в тонкости и бегут на хабр/стековерфлоу/другой блог и давай писать — JS га… о! Да как на этом можно писать!?! JS девелоперы слепые фанатики!

      Читал первую статью, потом вторую и вот третья появилась. Ребят, да оставьте кесарю кесарево. Вам удобно на C#/Java писать? Пишите, вас же никто не заставляет принудительно сменить стек технологий, потому что стильно/модно/молодежно.

      PS Пишу на JS уже лет 6-7 и прошел путь от «что-то подкрутить в jQuery» до сложных SPA для ERP/CRM систем, а так же архитектурных решений на NodeJS на серверной части.

      PSS пожалуйста, давайте без холивара.
      • +5

        Я просто пытаюсь намекнуть, что фанатизм не выражается в том, что кто-то с упоением пишет на JS. Большая часть статьи пестрит выражениями "ты думаешь" и "ты считаешь". Фанатизм — это больше психологическое. Он проявляется, когда человек начинает на каждом шагу проталкивать идею о том, что "мой язык — хороший, а все кто его не понимает — идиоты". Вот этот самый постфикс про идиотов и отличает фанатика от обычного разработчика. Я пытался вложить посыл "фуфуфу таким быть". :)

        • +5
          Так дело в том, что я наблюдаю фанатиков с обоих сторон. Кто-то пишет на Java и пытается доказать, что все остальное полная хрень и недостойно внимания и времени. Те, кто пишет на С# тоже пытаются доказать, что лучшего нет. И так далее, и так далее. И каждый с пеной у рта доказывает свою правоту, при этом пытается втоптать в дерьмо опоннента.

          И ломаются копья, и пишутся посты гнева. Зачем? Что кто кому пытается доказать?
          • +6

            Честно вам скажу, я думал "хм, а ведь в статье JavaScript можно заменить на любой другой язык". Но вот сугубо ИМХО, сугубо из моего опыта — разработчики на JS ведут себя подобным образом чаще. Я знаю Java-разработчиков, я знаю C++-разработчиков. Я даже знаю Haskell-разработчиков. Но самые громкие из них — JS-разработчики. Вот просто так получается по моей, вероятно нерепрезентативной выборке.

            • +3
              Мне кажется, что это из-за того, что JS язык молодой во второй реинкарнации. Я имею ввиду, то, что как нормальный язык он стал только последние 5-6 лет с приходом ES6. И в него влились молодые люди, котороым стоит поумерить самомнение и преобрести терпимости. И я таким был, но ничего, мы взрослеем, набираемся опыта.

              Думаю, надо научится уважать все стороны. И если кто-то кичится, то стоит человека на место ставить. Язык программирования тут не причем.
              • +4

                Тем не менее я убежден, что если человеку мягко не намекнуть что он ведет себя некрасиво — он сам не поймет.

                • +3
                  Абсолютно с вами согласен. Но еще раз уточню — язык программирования тут не причем.
                  • +2

                    … о чем и написано в шапке статьи.

              • +4
                Почитал бы такую статью о хаскелистах.
                • +9

                  Да там ничего интересного. Просто атрофируется возможность писать на языках без монад и к 8 уровню хочется строжайшей типизации для всего подряд, e.g. хочется иметь тип "циферки от 5 до 10.5"

                  • +8
                    Чёрт, хочется ведь :(
                    • +2

                      Ну включите саморефлексию и напишите :) Может мне еще и яичницу за вас приготовить? :)

                      • +6
                        Я не про статью, а про тип «циферки от 5 до 10.5».

                        Но это уже ближе ко всяким идрисам. Или ждём ghc 8.8, там обещали допилить зависимые типы.
                        • +3

                          Рефлексия упрощенно — саомкопание. "Саморефлексия" это уже что-то принципильно новое ;D дедлок какой-то. [/зануда]
                          Простите не удержался.

                          • +3
                            Да не, по идее, это идемпотентная операция, так что саморефлексия == рефлексия.
                            • +2

                              Без вики Вас не понял)) Да все верно, мое занудство ущемлено =)

                  • +15

                    Пишу (или когда-то писал) на Perl, PHP, JS, Java, C#, C++, Bash, XSLT, Python, ActionScript, Groovy, Lua. Наверняка что-то забыл упомянуть.


                    Во-первых, все вышеперечисленное дрянь, по тем или иным причинам :) Во-вторых, неперечисленное тоже дрянь.

                    • 0

                      От каждого по его способностям, каждому — по его труду ©

                    • 0
                      Пишу на 1С и не парюсь. Зачем все остальные языки?!
                      • 0
                        В случае 1С — это уже 8 уровень )))
                    • 0

                      А еще есть те, кто говорит «язык X — говно, но я на нём зарабатываю больше, чем на Y, поэтому на нём и пишу»...

                      • +1
                        Согласен с Вами, коллега, от холиваров фанатиков нет никакой пользы окружающим…
                        P.S. Сам я веб разработчик asp .net (C#), недавно дома начал пробовать писать игры на JS, сначала использовал jQuery, потом отказался от него, чтобы лучше изучить JS. Но ни востограюсь никакими языками и принципами, самое главное в нашем деле — простота и изящество решений, имхо…
                      • +2
                        Вот этот самый постфикс про идиотов и отличает фанатика от обычного разработчика

                        Ваша агрессивность фанатична
                        • +9

                          Заметьте, вовсе не js-разработчики всё это на Хабре начали.

                          • 0
                            Тоесть это адаптация этой статьи на тему JS?)
                          • –12
                            Пишу на JS уже лет 6-7

                            Бедненький, такое не лечится.
                          • –14
                            jQuery — удобный инструмент и искренне тебе помогает в делах

                            jQuery это устаревший инструмент, имеющий ряд недостатков. Для своего времени это был прорыв, позволяющий писать кроссбраузерный код без уродливых конструкций типа
                             var ua = window.navigator.userAgent;
                              var msie = ua.indexOf ( "MSIE " );
                            
                              if ( msie > 0 )      // If Internet Explorer, return version number
                                 return parseInt (ua.substring (msie+5, ua.indexOf (".", msie )));
                              else                 // If another browser, return 0
                                 return 0;
                            

                            да, так писали в 2010 году
                            Это был один из его плюсов тогда, но сегодня этого всего уже не нужно. Теперь о минусах, с jQuery очень легко писать с нуля, но очень тяжело поддерживать, потому что очень тяжело выявлять связи между кодом js и html разметкой. Как только проект становится больше hello world, очень легко, что то сломать и даже об этом не знать, потому что ошибок в консоли скорей всего не будет.
                            • +29

                              Слушайте, ей-богу, ваше мнение о jQuery тут никого не интересует. В контексте статьи фраза про jQuery означала "тебе комфортно в jQuery и ты не чувствуешь потребности в чем-то большем". Пожалуйста, смогите в переносный смысл. Я в вас верю.

                              • –4
                                да нет, мнение интересует кого-то
                                как раз интересно получить краткое мнение по поводу тезисов, и почему они смешны в этой статье — ведь мне некогда учить полностью весь необходимый стек, я работаю на другом дереве технологий

                                так что пускай люди пишут свои мнение
                                и ради бога, не думайте за всех
                                не пишите «никого не интересует»
                                • +4
                                  Людей который слишком много кричат про «jQuery не нужен» можно довольно легко ловить на простую двуходовочку:
                                  1. Просим их показать аналог jQuery.position()
                                  Они говорят да вот же!!1, смотрите как просто!
                                  2. А теперь нас интересуют координаты элемента, который обернут в элемент с position: absolute, а один из его родителей имеет position: fixed, и еще какой-то из родителей relative и там еще где-то margin'ов понапихано.

                                  Это в общем-то можно всё разрулить, но будет не она строчка, а десятка полтора. И по смыслу не будет отличаться от того, что внутри у jQuery.
                                  • +6

                                    Знаком с проблемой не понаслышке, но никому об этом не говорю :)

                                    • +8

                                      Заминусовали :( Вот именно поэтому и не говорю :(

                                    • +8
                                      А мы вот возьмем и вынесем эту функцию в новую библиотеку — шах и мат.
                                      • +6
                                        А потом вторую, третью, пятую, десятую…
                                        Ну а там и до пакетного менеджера недалеко, чтобы управлять ими.
                                        • –1

                                          То есть, вы предлагаете, если нужно использовать одну функцию из jQuery, тянуть всю jQuery в проект, если нужна одна функция из lodash, тянуть весь lodash и т.д.?

                                          • +1

                                            Ну вот смотрите: C/C++ компиляторы выбрасывают неиспользуемый код при компиляции, и для этого не нужно дробить библиотеки на элементарные. А вот в JS из-за особенностей языка так сделать нельзя, вот и приходится делать надстройки в виде пакетных менеджеров на каждый чих.

                                            • +5

                                              Справедливости ради, в webpack 2 поддерживается dead code elimination на уровне модулей, то есть import sortBy from 'lodash/sortBy' лишнюю часть лодэша при оптимизации отсечёт, если его правильно использовать.

                                            • +1
                                              Если реально одну — нет, но тогда и новая библиотека не нужна.
                                              Однако практика говорит, что одной дело ограничивается очень редко.
                                      • +2

                                        Тысячи людей используют, а вы говорите "не нужно". Нехорошо как-то, мы же не на дваче.

                                      • +5
                                        А еще «use jQuery» это известный мем на stackoverflow. По-моему в контексте статьи смотрится весьма органично. :)
                                      • +2
                                        нет никаких трудностей, если для обращений к элементам вы используете только id вместо html разметки и css классов

                                        как только вы фокусируетесь на id элементов, то ваша работа сводится к работе с моделью приложения и javascript + jquery, консоль в таком варианте незаменима

                                        проблемы большого проекта решаются разработкой грамотной модели приложения, а не отказом от jquery
                                      • –5
                                        Асинхронные операции в Node.JS для тебя — cutting edge. Ты полностью уверен, что ни в одном другом языке кроме как JavaScript это невозможно и никаким другим фреймворком кроме Node.JS это не поддерживается

                                        Хотя бы в ноде он (async/await) работает так, как ты этого ожидаешь, в отличие например от .net
                                        • +20

                                          … и вот мы определили ваш уровень поражения вирусом. :)

                                          • –1
                                            Не ставьте диагнозы ;) Пишите больше на js или лучше на ts, который на мой взгляд взял лучшее от js и c#. И тогда вы поймете, что то, что вам казалось разжижением мозга, на самом деле просветление.
                                            • +3

                                              Вы видимо шапку статьи не прочитали.

                                              • –1
                                                ts, который на мой взгляд взял лучшее от js и c#

                                                Чем ts лучше c#? =) Как по мне, ts хоть и улучшает js значительно, но до c# очень не дотягивает
                                            • +9

                                              Э… и в чем же отличие того как работает async/await в js и в .net? :-)

                                              • 0
                                                Тот же вопрос: в чём разница? Когда запустил NodeJS — понравилось, что async/await работает также как в C# (даже подумал: близнецы-братья), разве что дедлоков нет по Wait() или Result() — если синхронные операции вызываешь в асинхронном методе.
                                                • +30

                                                  Ну как же ты не видишь, слепец! В js это работает с магией, а в этом твоём c# работает с энтерпрайзным унынием! Как вообще это можно спутать?!

                                                  • 0

                                                    Ну да, потому что ни Wait, ни Result в js у обещаний нет :-)

                                                    • –6
                                                      Тот же вопрос: в чём разница?

                                                      разве что дедлоков нет

                                                      Хммм… действительно… в чём же разница… ;-)
                                                      • +2
                                                        разве что дедлоков нет по Wait() или Result() — если синхронные операции вызываешь в асинхронном методе.

                                                        Эта проблема решается просто: не используем синхронные операции вообще и используем свой планировщик. Да-да, механизм async-await — это просто синтаксический сахар, что в C# (обёртка над Task<>), что в JS (обёртка над Promise). Вам ничто не мешает в C# здесь так, чтобы абсолютно всё выполнялось в одном потоке, и никакие Wait() и Result() не будут нужны.

                                                        • –2

                                                          Синхронные операции не использовать вообще не получится. Типичный пример — обращение к асинхронной операции в конструкторе. Да, делать тяжелые операции в конструкторе не рекомендуется, но частично-инициализированный объект возвращать хуже. Да, можно написать фабрику, которая будет асинхронно создавать объект, но это не всегда применимо, в частности в случае наследования таких конструкторов.

                                                          • +1

                                                            Но это же не повод делать дедлок...

                                                  • +3
                                                    Я по причине обучения в ВУЗе столнулся с JS, до этого долго и упорно сидя на Lua. Ну первое время у меня матов не хватало, что бы описать JS, и если бы не jQuery, то возможно и сейчас бы не хватало.
                                                    • +6

                                                      У меня была та же реакция, когда я после JS врубался в Lua.

                                                      • 0

                                                        Слова вместо фигурных скобок не красиво соглашусь. То что функция может вернуть несколько результатов не привычно. Условия циклов и ветвлений можно обернуть в скобки чтобы выглядело привычно. То что всё можно использовать как ключь это круто. Правда пользовался этим только при сериалиации. То что конкатенация это отдельный оператор это плюс. С булевыми операциями всё просто. Всё true кроме false и nil.

                                                        • 0

                                                          «Всё как ключ» в общем удобно при работе с рекурсивными структурами. Не только сериализация, мне для конвертации в другие рекурсивные типы данных пригождалось (вроде из типов lua в C’шные структуры, используемые в другом языке программирования). Булевые операции в таком виде удобны, т.к. иногда позволяют обойтись без тернарного оператора. Но оператор был бы лучше.


                                                          Что мне категорически не нравится — это стандартная библиотека. io.popen не умеет даже такое малой части subprocess.Popen из Python как «не использовать shell» и «открыть одновременно на запись и чтение». setenv нет, хотя getenv есть. Конечно, в lua намеренно минимальная стандартная библиотека. Но я специально привёл примеры того, что я считаю присутствующим, но не полностью реализованным функционалом, а не тем, что вообще хотелось бы видеть в стандартной библиотеке.


                                                          Второе, что мне не нравится — совместимость. В lua её ломают, поэтому многие просто сидят на 5.1. Luajit до сих пор полностью совместим с 5.1, от 5.2 взято только то, что не нарушает совместимость, 5.3 в changelog вообще не упоминается. В Gentoo всё, кроме 5.1 замаскировано, maintainer’ы потихоньку монстрячат слотовый lua, чтобы ставить несколько версий lua одновременно — как я понял, множество пакетов в новой версии не работает и никто не хочет их чинить, поэтому выбирать не‐5.1 в качестве основной версии просто нельзя.

                                                          • +1

                                                            Нет, больше вымораживало отсутствие массивов.

                                                            • +1

                                                              Таблицы в Lua выполняют так-же роль массивов. В отличии от JS манипуляции с "массивами" выполняются внешними функциями но если очень нужно их можно и прицепить к таблице.


                                                              t = {"a", "b", "c"}
                                                              t.concat = table.concat
                                                              print (t:concat("*")) --> a*b*c

                                                              В JS то тоже чистых массивов нет. Это просто тот-же объект с дополнительными фунциями работы с массивом.


                                                              Таблица в Lua аналог обьекта в JS.

                                                              • +2

                                                                В PHP вроде тоже. Но это как‐то непривычно — я с Python и C на lua переходил. До 5.0, кстати, никаких оптимизаций для таких таблиц не было, всегда честный хэш (с соответствующей константой для вещей вроде table.insert), с 5.0 там гибрид массива и таблицы. table.insert всё равно, правда, не содержит оптимизаций вроде “если можно, просто запусти memmove()”, но гибридность снижает затраты на lua_rawget()+lua_rawset(). Тем не менее, судя по коду в 5.1 оператор # (длина) всё ещё О(log(N)). В 5.2—5.3 и luajit — не знаю.

                                                          • +1

                                                            http://moonscript.org/. Как CoffeeScript, только для lua.

                                                            • 0

                                                              Как‐то пытались использовать в Neovim, но отказались. Главная проблема: тесты на moonscript проваливались, никто не знал, почему. Другие проблемы:


                                                              1. Если вы сделали ошибку в синтаксисе lua напишет, какая и где была ошибка. Если вы сделали ошибку в синтаксисе moonscript, вы получите «Failed to parse», номер строки и всё.
                                                              2. Если вы сделали ошибку не в синтаксисе, то вы получите ошибку. А номер строки — нет, только номер строки в результирующем lua коде который в общем случае недоступен (вы можете сделать конвертацию локально, но вам нужна та же версия moonscript и, возможно, что‐то из окружения).
                                                              3. Moonscript отсутствует в репозиториях различных дистрибутивов. А у нас не lua пакет, чтобы ставиться из luarocks, где moonscript есть.
                                                              4. Линтеров практически нет. Я знаю только встроенный и moonpick, при чём второй не существовал во время принятия решения, а первый весьма ограничен.
                                                              5. Мажорная версия языка до сих пор 0, что означает, что язык будет считаться нестабильным. (Сам автор сказал, что он не использует semantic versioning и не считает язык нестабильным сам, но это скорее ещё один минус.)
                                                              6. Moonscript добавляет ещё один протекающий слой абстракции.
                                                              7. Людей, которые могут писать на moonscript неизбежно меньше тех, что могут писать на lua, потому что первые — подмножество вторых, потому что без знания lua отлаживать moonscript код нельзя.

                                                              Соответствующая дискуссия, окончившаяся тем, что текущий (@tarruda сейчас фактически не участвует в разработке) лидер проекта сказал, что будет использоваться moonscript, хотя больше людей было за lua. Пример неизвестных проблем с moonscript. Другой пример.

                                                        • +7
                                                          У вас ссылка на «JavaScript как праздник» введет туда же, куда и «JavaScript как явление».
                                                          однако мой основной профиль — C# и делать всё, чтобы защитить бедных C# разработчиков от излишнего ныряния в JavaScript.
                                                          «Бедные» C# разработчики не обязаны нырять с головой в JavaScript, если компания позволяет себе нанять отдельно разработчиков C# и JavaScript. Статья написана конечно же не для этого (по моему впечатлению). По вашей статье складывается впечатление, что все, кто пишет на более новых технологиях, чем JQuery — «больны».
                                                          Есть в уровнях (особенно последних двух) некоторые описанные симптомы, которые действительно кажутся маразмом, но не все. Например:
                                                          Едешь на конференцию по JavaScript. Там тебе впервые показывают как за 20 секунд сделать сервер на Node.JS. Восторгаешься. Вирус, подпитавшись материалами с конференции откусывает ту часть мозга, которая еще помнила про многопоточность. Она помирает и не успевает задать свои вопросы
                                                          Объясните, разве это плохо — ездить на конференции по своему языку программирования? Плохо, что в какой то технологии можно за 20 секунд сделать что-то?
                                                          Хочу обратить внимание, что первым появился пост, который обсирает JavaScript, и негодует его резкой популярности, второй же пост просто защищает JavaScript.
                                                          «Здоровый» человек не будет обсирать другую технологию, которую он не понимает, которая стала вдруг популярной. «Здоровый» человек напишет про свою любимую технологию. Не хочешь JavaScript на backend, не применяй (если ты решаешь чему быть), убеди тех. директора чем C# лучше JavaScript, не работай в компании с «больными» людьми, и все остальное в этом духе.
                                                          Мне кажется больше разводят холивар не JavaScript разработчики, а те, кто не являются JavaScript разработчиками, но кому приходится им пользоваться, ибо он сильно отличается от других.
                                                          • +9
                                                            У вас ссылка на «JavaScript как праздник» введет туда же, куда и «JavaScript как явление».

                                                            Fixed


                                                            По вашей статье складывается впечатление, что все, кто пишет на более новых технологиях

                                                            Нет, статья как раз о том, что тот, кто начинает считать свой любимый язык — звездой, а всех, кто не разделяет эту мысль — идиотами — тот больной. По стечению обстоятельств это происходит по мере усложнения используемых технологий.


                                                            Плохо, что в какой то технологии можно за 20 секунд сделать что-то?

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


                                                            «Здоровый» человек не будет обсирать другую технологию

                                                            Пост как раз об этом. В шапке же написано, что я критикую фанатиков, а не технологию

                                                            • +6
                                                              Плохо, если технология скрывает от тебя очень важный аспект реализации чего-либо, а ты сам не желаешь разобраться как оно все-таки работает.
                                                              Простите, но разве не этим же самым заняты 99,99 любых библиотек на любых языках, да собственно и самих языков высокого уровня? Это же всё направлено на то, чтобы ты не воевал с инструментом за каждый шажок, а занимался решением своей прямой задачи.
                                                              • +1

                                                                Все верно. Однако — опять же — в хороших ВУЗах зачем-то изучают что такое стэк, как передаются параметры в функцию и вообще учат C. Если ты хотя бы ориентировочно понимаешь как и что работает — это помогает идентифицировать и обезвредить любой потенциальный факап, который может возникнуть с технологией. В случае многопоточного программирования — даже в node.js можно поймать race condition. И вот представьте что вы наткнулись на race condition, а вы не знаете что это :)

                                                                • –3
                                                                  А что, в C нельзя устроить race condition, не понимая что это такое? Он настолько сложен, что без 5 лет учёбы в ВУЗе на нём нельзя сделать такую тривиальную вещь, как параллельный/асинхронный блок кода?
                                                                  Да и тем более, race condition он что, спалит вам компьютер и аннигилирует вселенную, если вы за 5 секунд его не нейтрализуете? Для его устранения нужны какие-то сакральные знания, которые нельзя восполнить в пределах 15 минут?
                                                                  • +5

                                                                    Эаам…
                                                                    Наоборот — на C очень легко сделать race condition с posix-тредами и натренироваться такие ситуации подмечать и бороться с ними.

                                                                    • –5
                                                                      Тогда я вообще не понимаю. Вы ругаете язык за то, что в нём сложнее отстрелить себе ногу, потому что отстреливая себе ногу гораздо легче научиться не отстреливать себе ногу?
                                                                      • +6

                                                                        Послушайте, я не ругаю языки. Я ругаю людей, которые не учатся основам перед тем, как начать делать что-то серьезное.

                                                                    • +6

                                                                      Да, для устранения race condition нужны знания, которые нельзя восполнить за 15 минут. Очень интересно наблюдать, как такие проблемы решают разработчики с завышенным самомнением — обвешивают костылями, а потом отмазываются — php наверное сбоит. Любые абстракции текут, поэтому фундамент нужно знать.

                                                                • –3

                                                                  Я не очень понимаю.
                                                                  C# / C++ / Haskell / Java / etc -разработчики активно нападают на JS.
                                                                  Js-разработчики защищают свой язык.


                                                                  Фанатики как раз первые, а вовсе не вторые. Почему вы написали пост про js-фанатиков, а не haskell-фанатиков или c#-фанатиков?

                                                                  • +12

                                                                    Я вот фанатиков от этих языков особо как-то не встречал. Сообщества ведут себя абсолютно адекватно, не строят из своих технологий серебрянную пулю и не считают быдлом всех, кто не пишет на %язык_нейм%, не общаются рекламными штампами. Кроме того, относительно адекватно реагируют на вопросы. E.g. каждый раз, когда я задавал вопрос по C++/Java любому из опытных разработчиков на оных — я спокойно получал ответ и разъяснение как и что работает. Каждый раз, когда я задавал вопрос по JS-у, я получал в ответ упреки, что я ничего не понимаю, мне надо учить самые основы и вообще "не умеешь — не лезь". Так один из адептов рассказывал мне снисходительным тоном про прототипное наследование — будто Америку открывает. Делал он это в ответ на вопрос о виртуализации прокрутки. И такие ситуации возникли несколько раз подряд — вот я и подумал что что-то с разработчиками на JS не так. Когда они начали отрицать индустриально-базовые вещи, такие как строгая типизация и многопоточность — я понял что под видом сакрального знания чаще всего подают вопиющую неквалифицированность. Ну я не выдержал и все заверте… Я просто скомпилировал все штампы, которые слышал в одну отдельную статью

                                                                    • +5

                                                                      Это фанатиков хаскеля-то вы не встречали? Видимо, вы мало с ними общались. Более яростных теоретиков, далёких от бизнеса, я никогда не видел. Фанатики C++, которые всё что выше C++11 называют хипстотой — тоже интересные личности.
                                                                      C# и Java — встречал мало, да. С этим лучше.

                                                                      • +3

                                                                        Понимаете в чем дело, ни фанаты haskell, ни фанаты C++ не станут подвергать сомнению такие базовые дисциплины как операционные системы, сетевые технологии, базы данных или теория типов. В отличие от.


                                                                        Они могут сказать что я пишу на не труъ-языке, но они никогда не скажут что многопоточность — это плохо.

                                                                        • –9
                                                                          Многопоточность это сложно, а сложно это плохо. Согласитесь, без неё мир был бы проще. Просто есть задачи, которые без многопоточности решаются еще сложнее. И кстати многие среды выполнения JS внутри используют потоки. Взять тот же node.js, не говоря уже о браузерах.
                                                                          • +4

                                                                            Промышленная химия — это сложно. А сложно это плохо. Согласитесь, без лекарств мир был бы проще.


                                                                            Просто, как вы заметили, без лекарств людям жить еще хуже :)

                                                                            • –4
                                                                              Просто, как вы заметили,

                                                                              Ну что уж так уж?). Самые крутые истории, которые доходили из поддержки, связаны с эффектами, возникавшими в многопоточных приложениях. Не знаю какими таблетками кормят разработчиков, может такими когда приходится выбирать или печень, или почки.

                                                                              Вы не поверите, но это реально круто, когда код можно тупо дебажить, покрывать юнит-тестами, а потом он реально так и работает.
                                                                              • +1

                                                                                Как вы покроете юнит-тестами конструкцию "показывать пользователю UI, давать работать с локальной копией БД, в то же время пытаться установить подключение к серверу с увеличивающимися интервалами в 10, 20, 30 сек и далее минута, но отвалиться после 5 попыток"?

                                                                                • 0
                                                                                  Мы сейчас точно говорим про юнит-тест (это которые должны тестировать SUT, абстрагировав от всех внешних зависимостей?) Мне почему-то кажется, что функцию которую вы описали, надо покрывать матом — слишком много на себя берет. :)

                                                                                  Во всех реализациях JS таймер является внешней штуковиной, которая благодаря этому тривиально заменяется на фейк. Например такой http://legacy.sinonjs.org/docs/#clock. Все предельно просто, как в детском конструкторе, и это правда работает.
                                                                                  • +1

                                                                                    При чем здесь таймер? Я вам не про функцию говорю, а про целую систему. Вы можете покрыть 2 потока отдельными тестами, но интеграционно вам придется тестировать это вручную.

                                                                                    • +2
                                                                                      Можно вспомнить, что многопоточность — это монада, и сделать аналог quickcheck-подобного тестирования для всех возможных последовательных представлений двух потоков (возможно, со снапшотами состояний для каждого из потоков, ибо race condition'ы же тоже надо уметь тестировать).
                                                                                      • +2

                                                                                        Извините, я на вашем клингонском не говорю :)

                                                                                        • +2
                                                                                          Ну для этого как минимум операции должны быть атомарными, а скорость роста всех возможных перестановок явно отобьет охоту проверять все возможные ситуации :)
                                                                                          Я не говорю еще про инвалидацию кэша процессоров, оптимизации компиляторов и пр.низкоуровневые вещи, меняющие выполнение операций.

                                                                                          Да, жизнь боль :(
                                                                                          • 0
                                                                                            Не обязательно проверять все возможные пути исполнения, их действительно многовато.

                                                                                            Ну а что до кэшей и оптимизаций компиляторов — представляется разумным (формально) проверять это отдельно и единожды, а затем рассчитывать на это как на работающий и доказанный примитив.
                                                                                        • +1
                                                                                          Прикол в том, что 2 потока отдельными тестами это имитация бурной деятельности. 2 потока в тесте и 20К потоков при эксплуатации могут давать совершенно разную картину для одной и той же сборки. А это, в свою очередь, резонно порождает отдельную пачку вопросов относительно практической полезности и экономической оправданности таких тестов в контексте раннего обнаружения класса багов, специфичного лишь для многопточного кода.

                                                                                          Выпад про интеграционные тесты, если честно, не понял. Мой тезис был конкретно про юнит, ибо это база. Для end-to-end тестов в условиях приближенным к боевым, существуют свои решения как для ручного так и для автоматического тестирования.
                                                                                • 0

                                                                                  Вот вы и сами видите. Фанат haskell не скажет, что многопоточность, это плохо. Он хотя бы про видеокарты вспомнит, там многопоточность — это хорошо. А вы сказали, даже объяснение придумали. В этом разница.

                                                                                  • +1
                                                                                    Фанат хаскель, если он конечно не разработчик ghc, скажет, что тождественный функтор для единичного морфизма это хорошо.) А многопоточность, ей богу — пофик — компилятор умный, вот пусть и думает как параллелить.
                                                                                    • +1
                                                                                      А многопоточность, ей богу — пофик — компилятор умный, вот пусть и думает как параллелить.

                                                                                      Я так на первом году жизни работы с хаскелем думал, но только вот понять, что map fibonacci [0..1000] для наивной рекурсивной реализации Фибоначчи ­— дорогая штука, и её лучше распараллелить, а map (*2) [0..1000] — нет, не очень тривиально.

                                                                                      Но вы правы, в подавляющем большинстве случаев параллелизм достигается заменой map на parMap rdeepseq, а конкурентность — каким-нибудь forkIO в main.

                                                                                      Забавно, кстати, как раз сейчас нашёл баг в ghc, который выкидывает некоторые аннотации параллелизма.
                                                                                      • 0
                                                                                        Тогда можно еще задачу комивояжора припомнить (и вообще там целый класс задач из мира «очевидное-невероятное программирование», ни чем не хуже, чем «1 + '2' == '2' + 1» в JS). А про фанатов это конечно под впечатлением шутливого тона статьи. Правда, если воспринимать буквы совсем буквально, то меня можно и канделябром (запрещено законом РФ). Только вместе с автором, ведь не я первый здесь это начал.
                                                                                        • +3
                                                                                          Я не очень понимаю, как вы сравниваете задачу коммивояжера и типизацию в JS. Наверное, это всё от слабой типизации.
                                                                                          • 0
                                                                                            Сожалею, что пример оказался путанным. Я имел ввиду задачи, где глядя на код, результат не совсем всегда очевиден. В случае map fibonacci и задачи нахождения оптимального пути в графе в хаскеле получается неожиданно плохая асимптотика. По-моему это ни чем не лучше, чем приколы с приведением типов в JS.
                                                                                            • 0
                                                                                              Я имел ввиду задачи, где глядя на код, результат не совсем всегда очевиден.

                                                                                              У любой оформленной в виде кода задачи есть intrinsic complexity (этакая неизбежно связанная с ней сложность), сложность, связанная с языком (ну трудно писать на брейнфаке, что поделать) и сложность, связанная с радиусом кривизны рук программиста. Когда результат не совсем очевиден только для задач с большой intrinsic complexity, это хороший, годный язык.

                                                                                              В случае map fibonacci и задачи нахождения оптимального пути в графе в хаскеле получается неожиданно плохая асимптотика.

                                                                                              Смотря как написано fibonacci. Если это каноничная рекурсивная реализация, то вести она себя будет действительно паршиво, но она в любом языке будет вести себя паршиво. Мемоизирующую реализацию написать довольно просто за счёт свойств языка:
                                                                                              fib = (fibs !!)
                                                                                                  where fibs = 1 : 1 : zipWith (+) fibs (tail fibs)
                                                                                              


                                                                                              А с оптимальным путём — что здесь не так?
                                                                                              • –2

                                                                                                … и эта самая мемоизирующая реализация все еще в связке с map будет работать медленнее чем хотелось бы, хоть и не будет уже так тормозить.

                                                                                                • –1
                                                                                                  Мы ж про асимптотику, а не про константу ;)

                                                                                                  Если вы о том, что!!! — O(n), то возьмите Data.Array вместо обычного списка, и будет примерно то же самое, что и для императивного нечистого языка. Если хотите, чтобы результаты шарились между разными вызовами — ну, вам нужно будет ST или IO уже тогда, глобальный стейт же, и это правильно.
                                                                                  • 0

                                                                                    Если бы не было многопоточности, мы бы до сих пор сидели бы на древних компутерах.

                                                                                    • +2
                                                                                      Многопоточность — сложно по сравнению с использованием callback?
                                                                                      • +2
                                                                                        Многопоточность это сложно, а сложно это плохо

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


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

                                                                                      • +1
                                                                                        Многопоточность — это не плохо. И не хорошо. Просто в рассуждениях о node.js, противопоставляя его многопроцессному подходу, смешивают в кучу «людей и коней».

                                                                                        Ведь все пользуются однопоточным nginx для статики, не так ли? Так вот. Всем же очевидны его преимущества? Так вот. Типовая модель использования node.js — та же: «принеси-подай» из базы. Накладных на преобразование http-запроса в sql/mongodb-запрос практически нет (ну не более чем nginx резолвит filename:)). Забрать из базы данные — почти та же статика, которая не содержит логики обработки по запросу (в отличие от типичного рендеринга в PHP). Чтение файла — такая же асинхронная операция, как и выборка.

                                                                                        Стандартный способ деплоя node.js — это pm2, который кластеризует процессы node по ядрам. По сути, мы перещаем бутылочное горлышко рендеринга из серверных процессов на клиента (в современных virtual dom-технологиях и серверах api на node.js по типу loopback). То есть нагрузку на сервер облегчаем, и это честно так.

                                                                                        И кстати, многопоточность — это плохо, когда накладные на переключение начинают влиять. Разница между процессами и потоками с точки зрения ОС небольшая (общая память => общий краш для потоков, для процессов нет), и вряд ли кто поспорит, что 4 процесса по 1000 коннектов лучше 4000 потоков (пусть даже не процессов) в системе. Банальный fork в линухах должен будет скопировать окружение процесса, проинициализировать процесс и прочие приседания на синхронизацию (где-то родительский поток ждет или поллит семафор заверешения чайлда).

                                                                                        Я вот не говорю, еще раз, что многопоточность плохо (или хорошо). Я говорю о том, что рассуждать о ней надо в контексте конкретной системы.
                                                                                        • +3
                                                                                          Ведь все пользуются однопоточным nginx для статики, не так ли?
                                                                                          Мир клином не сошелся на IO-bound задачах. Более того, IO-bound задач настолько мало, что их обычно изолируют и забывают (тот же nginx например).

                                                                                          Типовая модель использования node.js — та же: «принеси-подай» из базы
                                                                                          Да-да, в простонародье — формошлепство (а точнее, его бекенд). Почему же тогда фанаты JS начинают брызгать слюной, когда им говорят что их язык не годится для чего-то более серьезного? (ну, или, более толерантно, подходит хуже чем другие промышленные языки).

                                                                                          Я вот не говорю, еще раз, что многопоточность плохо (или хорошо). Я говорю о том, что рассуждать о ней надо в контексте конкретной системы.
                                                                                          Вообще-то в прошлых тредах (да и в этих тоже) фанаты утверждали, что многопоточность не нужна вообще, потому что слишком сложно. А это подразумевает как раз отсутствие контекста. За что их и высмеивали.
                                                                                          • 0
                                                                                            чего-то более серьезного

                                                                                            Пример вам под руку: написать GET-метод, который полезет в БД, достанет оттуда данные, соберет из них excel-файл и отправит клиенту. Вот тебе бабушка и IO-bound задачи юрьев день

                                                                                            • +3
                                                                                              Самое печальное, что так ведь и делают: крутят в одном потоке как генерацию xls, так и асинхронный чатик. И потом еще не верят что чатик зависает. У нас же NodeJS, это невозможно! Но если что, виноваты конечно же программисты, а не экосистема, которая их воспитала.
                                                                                              • –2

                                                                                                Вот мы и нашли тонкую грань между хеллоуворлдом и серьезным проектом. Если для всей необходимой функциональности достаточно IO-bound операций (сериализация/десериализация не в счет), то вы пишете хеллоуворлд.

                                                                                              • +2

                                                                                                Ну, проблемы генерации больших excel-файлов на количестве потоков не заканчиваются. Так что тут node.js и C# для меня одинаковы — в обоих случаях я предпочту вынести генерацию файла в отдельный процесс :-)

                                                                                                • +1

                                                                                                  Генерация-то ладно, она обычно не раздувается по памяти и CPU до бесконечности. А вот парсинг — может, как уже не раз показывал опыт с Apache POI, PDFBox и Tika.

                                                                                                  • –1

                                                                                                    Не скажите. Мне вот в этом году пришлось фиксить багу вида "после выгрузки в Excel справочника на 100000 строк сервер перестает отвечать". Правда, эта ошибка воспроизводилась только в тестовой среде, где веб-сервер и сервер СУБД за память воюют — но в другой процесс генерацию я все равно в итоге вынес.

                                                                                              • 0
                                                                                                Я повторюсь. Обработку картинок нейросетью на сервере я не буду писать на node.js. То что называют «формошлепством» — далековато от истины в случае того же loopback, который можно настроить на абсолютно всё.

                                                                                                Я противник лишней работы на сервере, и считаю, что для большинства современных задач (работаю в немаленькой веб-студии), скажем > 80%, node.js более чем достаточно.
                                                                                                • +1
                                                                                                  что для большинства современных задач (работаю в немаленькой веб-студии)

                                                                                                  Наверное, вы хотели сказать "для большинства задач веб-студии".

                                                                                                • 0

                                                                                                  Мы в каких-то видимо сильно разных мирах живём, но как мне видится пласт задач вида "сходи в базу, принеси A, потом прими решение на его основе и принеси Б" — довольно широкий и охватывает если не весь веб, то довольно серьезную его часть.


                                                                                                  Разумеется, есть еще уйма CPU-bound задач, которые на ноду ложатся мягко говоря не очень. Но это ведь не делает ноду плохим инструментом, для решения io-bound задач.


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

                                                                                                  • +2

                                                                                                    Вот статья, рассказывающая о том, как работает nginx. Суть её — вся магия работает покуда у вас только io-bound операции. А nginx как раз для таких и предназначен (раздача файлов, статический контент). А вот другая, не менее объемная статья о том, как сложно nginx-у жить с cpu-bound операциями и как он вынужден с ними справляться. Повторяю еще раз. Насущная CPU-bound операция для бизнеса, например — генерация документов (тот же самый excel). И покуда остаются проекты с cpu-bound операциями (а почти все серьезные проекты именно таковы) путь для nodejs в мир серьезного продакшена закрыт.

                                                                                                    • +1

                                                                                                      Ну с чего бы закрыт-то? Просто надо в отдельные потоки или процессы такие операции выносить.

                                                                                                      • +1

                                                                                                        А это уже многопоточность. Это уже, как выше было JS-разработчиками сказано, сложно. А сложность, как они же нам объяснили — не нужна :)

                                                                                                        • +1

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

                                                                                                          • +1

                                                                                                            И через что будет строиться этот обмен сообщениями? Shared memory? Добро пожаловать в мир всего того, что вы сказали. Пайпы? Попрощайтесь с кроссплатформенностью. Сетевые сокеты? Ну вариант, но как по мне — серверное приложение, которое подключается само к себе выглядит как минимум странно.


                                                                                                            Плюс к тому же — если я правильно врубаюсь, то nodejs как раз активно пытается уйти от излишних потоков в пользу архитектуры а-ля nginx. Однако во-первых тредпул она уже активно использует, во-вторых… будет еще один? :) Так или иначе разработчикам придется управлять потоками. А они, как сами дают понять — не умеют.

                                                                                                            • 0

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

                                                                                                              • 0

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

                                                                                                                • +1

                                                                                                                  А зачем нужен сложный обмен сообщениями, чтобы построить xls в отдельном потоке? Запустили процесс и ждем ответа. Я бы сделал как-то так:


                                                                                                                  const exec = require('execa');
                                                                                                                  
                                                                                                                  app.get('/get-xls', async (req, res) => {
                                                                                                                     const params = getParamsFromRequest(req);
                                                                                                                     const data = await db.requestData(params);
                                                                                                                  
                                                                                                                     const {stdout} = await exec('node', ['./generate-xls', data]);
                                                                                                                     res.send(stdout);
                                                                                                                  });
                                                                                                                  • 0

                                                                                                                    Как-то странно вы данные через командную строку передали. Они же структурированные и их много. Да и итоговую xls в памяти держать — тоже неправильно. И обработка ошибок нужна...

                                                                                                                    • 0

                                                                                                                      Данные предполагалось передавать чем-то типа json в виде аргумента командной строки. Все равно любые сообщения между процессами это строки, так что сериализовывать придется.


                                                                                                                      А если не нравится загружать весь xls в память, то можно взять stdout как поток и через pipe завернуть его в response.


                                                                                                                      Получилось бы больше кода, но не страшно.

                                                                                                                      • 0

                                                                                                                        В файл её и отдать через sendFile

                                                                                                                        • –1

                                                                                                                          Я думал об этом варианте, в памяти с данными работать быстрее, чем писать на диск. (Мы же не делаем XLS-таблицы на 8 Гб?)


                                                                                                                          В любом случае, варианты есть, а утверждение автора pnovikov, что в node.js все плохо с многоточностью/многопроцессностью — неверно

                                                                                                                          • 0

                                                                                                                            Да варианты-то есть всегда. Просто, например, в C#/MVC генерация xls (cpu-bound) не является проблемой вообще и никаких "вариантов" для неё не надо — берешь и пишешь (с асинками разумеется)

                                                                                                                            • +1

                                                                                                                              2 гигабайта в последнем поколении сборщик мусора не собирает пока его не пнуть. А после пинка — собирает довольно долго...


                                                                                                                              Я бы не говорил что в C#/MVC генерация xls не является проблемой вообще.

                                                                                                                        • 0

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

                                                                                                                          • 0

                                                                                                                            Верно, совсем забыл про stdin. C ним будет намного лучше!

                                                                                                                    • +1

                                                                                                                      Так message-based IPC в event-driven языке с managed memory и async/await искоробки, это так же просто и прямо как котят гладить.

                                                                                                                      • +1

                                                                                                                        Это Erlang. Ну или C# с Akka. Но JS-разработчики так не хотят. Они хотят Javascript :)

                                                                                                                  • +1
                                                                                                                    Пайпы? Попрощайтесь с кроссплатформенностью.

                                                                                                                    Эмгм. Что у QLocalSocket, что у System.IO.Pipes проблем с кроссплатформенностью не наблюдал. Причём у второго не наблюдал даже во времена Mono 2.6.


                                                                                                                    Просьба пояснить, что имелось ввиду.

                                                                                                            • –2

                                                                                                              После прочтения статьи я немного удивился: ни в Windows, ни в Linux нет полноценной возможности асинхронно читать файлы.

                                                                                                              • +3

                                                                                                                Постойте, я и не говорю, что нода хороша для CPU-bound операций. Больших фишек у ноды ровно две:


                                                                                                                1. асинхронный io с приятным интерфейсом для простых смертных (нет, последователи Карри, для этого не нужна специальная монада, и да, парни из мира Стандартных Изданий, для этого не нужно упражняться с тредпуллами), который внезапно показывает весьма приятную производительности без лишнего тюнинга.
                                                                                                                2. javascript. Который, внезапно, не смотря на все фу-фу-фу, доступен практически любому разработчику на Java, C, C++, C#, Pascal, PHP итд. А если немного подтянуть матчать и разобраться в том как работает this и прототипное наследование (которое, вообще говоря надмножество Java-like OOP), то внезапно оказывается, что это вполне пристойный инструмент. А если копнуть еще чуть глубже, то внезапно оказывается, что JS можно декорировать типами (flow), проверять линтерами, собирать под платформы разной степени древности (babel) и использовать фичи из черновиков грядущих стандартов прямо вот сейчас (опять, привет babel). Чем, не смотря на некоторую костыльность и соберисамность, может похвастаться далеко не каждый ЯП.

                                                                                                                Теперь про CPU-bound и тот-самый excel. Я конечно в офисных xml делах не очень рублю, но что-то мне подсказывает, что если мы собираемся массово генерировать excel- файлики, то я бы предпочёл это действо передавать системе и вызывать отдельным процессом. Потому что наверняка есть хорошая сторонняя/системная тулза, которую не стоит пытаться запихнуть ни в ноду, ни в похапэ, ни в питон.


                                                                                                                Это не значит, что надо писать на ноде всё и вся. Но для типовых веб-серверных задач нода — прекрасный, доступный и достаточно мощный инструмент.

                                                                                                                • –2
                                                                                                                  Я бы взял какой-нибудь js-xslx и генерил бы файлики на клиенте. Если нужен один файлик на много скачиваний… да, придется делать его на сервере (в таких случаях обычно это редкий запрос). Можно дернуть процесс (опять хоть с тем же js-xslx), хотя в доках по js-xlsx виден метод writeFileAsync (с коллбэком).
                                                                                                                  • +3
                                                                                                                    Я бы взял какой-нибудь js-xslx и генерил бы файлики на клиенте

                                                                                                                    Хватит! Люди. Не везде и не у каждого суперкомпьютер. Тестируете своё приложение на своих машинах с 16 гб памяти и core i7. И думаете что всё в порядке. Любой чих перекладываете на клиент, что бы не дай бог сервер не загрустил… Вы там на адруино приложения хостите что ли?! Генерировать файл на клиенте…
                                                                                                                    • +1

                                                                                                                      А в чем проблема? Eсли речь идет не о 8гб таблиц, то до определенного предела фронтенд вполне себе в состоянии из json получить xml.


                                                                                                                      Разумеется, если киллер-фича приложения это генерирование xlsx на любой кофеварке с браузером, то нужно крепко подумать, желательно дважды. Но если речь идёт о данных, которые уже есть в вебе и их не десятки мегабайт, то в чем проблема? Современные движки JS достаточно быстрые для этого.

                                                                                                                    • +2
                                                                                                                      > Я бы взял какой-нибудь js-xslx и генерил бы файлики на клиенте
                                                                                                                      Прям вот квинтэссенция того, за что я не люблю современных жсников.
                                                                                                            • 0
                                                                                                              По сути, мы перещаем бутылочное горлышко рендеринга из серверных процессов на клиента

                                                                                                              Мне кажется, этот момент наступил с повсеместным переходом на толстые фреймворки, требующие для работы много ресурсов. И рендеринг на стороне клиента — просто попытка оправдания использования новомодных технологий.


                                                                                                              Если рендеринг является бутылочным горлышком — распараллельте его. Все равно процессорное время, затрачиваемое БД на обработку запросов, много больше времени рендеринга.


                                                                                                              Почему-то Facebook, ВКонтакте до сих пор используют PHP. Можете это пояснить?


                                                                                                              И кстати, многопоточность — это плохо, когда накладные на переключение начинают влиять.

                                                                                                              На самом деле, асинхронность — та же самая разновидность многопоточности. Принципиальная разница здесь заключается только в том, что в одном случае планировщиком задач является сама операционная система, а в другом — пользовательское приложение. И в случае ручного переключения задач мы вполне можем добиться экономии на многих вещах: на переключении контекстов, на примитивах синхронизации.


                                                                                                              Кстати, что-то подобное было в Windows 3.1, когда приложения (процессы?) работали в многозадачном режиме, но приложения в явном виде сообщали системе (DoEvents), что они готовы передать управление в другое приложение.

                                                                                                              • +1
                                                                                                                • –1
                                                                                                                  Асинхронность говорит лишь о порядке выполнения, который не важен, в отличие от синхронного, и больше ни о чем (о разновидностях многозадачности упоминать еще рано). Но это, вроде бы простое, свойство открывает ряд интересных возможностей для применения различных стратегий выполнения такого кода, что будет принципиальным образом сказываться на производительности и отзывчивости.
                                                                                                                  • 0

                                                                                                                    Вставлю 5 копеек внеапно, в защиту JS.


                                                                                                                    рендеринг на стороне клиента — просто попытка оправдания использования новомодных технологий

                                                                                                                    Да нет, вы знаете, зачастую бывает очень уместно переложить монотонную конкатенацию строк на клиентскую машину. Тут, конечно, важно не перегибать, но в общем и целом рендеринг HTML-я, если так, по-хорошему — это не очень релевантная для сервера задача. Чисто концептуально, если её можно перекинуть на клиента, который бьет баклуши — я лично, с позиции бекенда, был бы только за. Другое дело что встают вопросы с индексированием… Но это уже к самой концепции отношения не имеет.


                                                                                                                    Если рендеринг является бутылочным горлышком — распараллельте его

                                                                                                                    Рендеринг не параллелится в общем случае. Максимум что можно — сделать его поточным. Чтобы соединить пайплайн отрисовки и записи в сокет. Но и тут все сложно.

                                                                                                                    • 0

                                                                                                                      А что думаете насчёт связки изоморфное фронт-приложение + API-бэкенд?

                                                                                                                      • 0

                                                                                                                        Думаю что backend на JS — это очень плохая идея. Поэтому изоморфизм в общем случае не взлетит, покуда у нас нет технологии для изоморфного рендеринга не на JS.