Задать вопрос
  • Как переделать из нативных переменных?

    bingo347
    @bingo347 Куратор тега HTML
    Crazy on performance...
    Комментировать
  • Сравнение строк JS?

    bingo347
    @bingo347 Куратор тега JavaScript
    Crazy on performance...
    Комментировать
  • Как асинхронная программа(event loop) понимает, что пришел ответ от сервера?

    bingo347
    @bingo347
    Crazy on performance...
    Что-бы понять асинхронность полностью придется постепенно опустится на самый низкий уровень, вплоть до железа. Но начать стоит с самого верха - с уровня нашего приложения.

    Итак, мы пишем на нашем высокоуровневом любимом языке, неважно JS/Rust/C#/Scala/Python или любой другой. В современном мире у нас скорее всего есть какая либо абстракция для работы с асинхронными апи, предоставляемая или стандартной библиотекой языка или сторонними библиотеками. Она может быть примитивной и основанной на колбэках или более продвинутой, вроде Future/Promise/Task или чем-то подобным. Иногда наш язык предоставляет синтаксис наподобие async/await для более простой работы с этими абстракциями, а иногда асинхронная работа может вообще быть скрыта от нас в рантайме языка, например как с горутинами в Go. Но в любом случае где-то под капотом у нас будет event-loop, а иногда и не один, так как никто не запрещает нам писать многопоточку в то же время используя асинхронные вызовы.

    Сам event-loop - это не более чем обычный while(true) или любой другой бесконечный цикл. И внутри этого цикла наша программа имеет доступ на извлечение к некоторой очереди (если не знаете, что это за структура данных, то погуглите), которая содержит в себе результаты уже обработанных задач. Программа берет очередной результат, находит ожидающий ее колбэк/Promise/Future/Task и запускает выполнение ожидающего кода. Очередей опять же может быть несколько и обрабатываться они могут по разному, но это не важно. Важно то, что наш основной поток (или потоки) ничего не знают, о том как выполняются асинхронные задачи. Он лишь смотрит, есть ли в очереди результат, и если есть - обрабатывает его, а если нет, то принимает решение или выйти из цикла (и завершить поток, а иногда и весь процесс) или уснуть пока новых результатов не появится.

    Но откуда же в очереди берутся результаты? Надо понимать, что асинхронная программа почти всегда многопоточная и результат операций попадает в очередь из фоновых потоков, которые просто блокируются в ожидании нужного ресурса (или сразу многих ресурсов, если используют системные апи вроде epoll или kqueue). Как правило такие фоновые потоки большую часть времени находятся в состоянии ожидания, а значит не потребляют ресурсы CPU и не попадают в планировщик ОС. Такая простая модель действительно позволяет сильно экономить ресурсы по сравнению с моделью, где множество потоков выполняют по 1 задаче и самостоятельно ожидают свои запросы.

    Важно отметить, что в современном мире даже на среднеуровневых языках, вроде C или C++, не говоря уже о высокоуровневых, не реализуют асинхронность сами. Во-первых, на разных ОС для этого используются разные апи. Во-вторых, эти апи на разных ОС умеют обрабатывать разные типы ресурсов (с сетью вроде как умеют работать все основные ОС, но помимо сети асинхронно можно работать с пользовательским вводом, диском и периферийными устройствами, вроде сканеров, вебкамер и прочего цепляемого в usb). Наибольшую популярность (ИМХО) имеет кроссплатформенная библиотека libuv, хотя в Rust принято использовать mio (или даже абстракции над ней, вроде tokio), в C# подобные механизмы есть в .NET Core, а в Go оно уже зашито
    в те самые 1.5МБ рантайма, что Go засовывает в каждый бинарь
    (там правда еще и GC, но один фик это много и достойно вынесения в динамическую либу)


    Ок. С прикладным кодом вроде разобрались. А что же происходит в ядре ОС? Ведь, как писалось выше, у нас даже есть апи, чтоб ждать запросы пачкой. Все просто. Ядра ОС стали асинхронными еще до того, как это стало мейнстримом, если мы конечно имеем дело не с ОС реального времени (но у нас же винда/линь/мак/фряха, а не ОС для бортового компа боинга, где это критично). Смотрите, когда что-то происходит на внешней периферии (ну например диск запрошенные данные прочитал или по сети данные пришли, или юзер мышкой дернул), то формируется прерывание. CPU реально прерывает свою текущую работу и бежит смотреть что случилось, точнее вызывает обработчик предоставленный ОС. Но у ОС то есть основная работа, поэтому она скорее старается освободить обработчик и просто скидывает все данные в оперативку, а разбираться будет потом, когда очередь дойдет. Ничего не напоминает? Очень похоже, на то что происходило в event-loop, только вместо фоновых потоков "результаты" попадают в очередь из прерываний. А уже когда-то потом ОС отдаст данные в драйвер устройства, ну и т.д., пока они не дойдут до нашего прикладного приложения. Вот и все, никакой магии.
    Ответ написан
    3 комментария
  • Какой тип для event нужно прописать?

    bingo347
    @bingo347 Куратор тега TypeScript
    Crazy on performance...
    type TypescriptInferTheEventTypeForMePlease
        = HTMLSelectElement['addEventListener'] extends ((
            eventName: 'change',
            cb: (event: infer E) => any
        ) => any)
        ? E
        : never;

    P.S. VSCode говорит что это просто Event
    Ответ написан
    Комментировать
  • Как изменять значение стрима после метода subscribe?

    bingo347
    @bingo347 Куратор тега JavaScript
    Crazy on performance...
    Комментировать
  • Как установить программу с расширением tar.xz?

    bingo347
    @bingo347
    Crazy on performance...
    Скорее всего Вам надо https://wiki.archlinux.org/index.php/AUR_helpers
    сам лично использую yaourt
    Ответ написан
    Комментировать
  • NUXT, как в serverMiddleware правильно передать данные в asyncData?

    bingo347
    @bingo347
    Crazy on performance...
    Как по человечески сделать?
    никак, nuxt мартышки делали, а не люди...
    Нашел один способ - через костыли - прицеплять данные к req.
    к сожалению это единственный способ сделать +/- адекватно, не гоняя при этом запросы через axios
    Ответ написан
    Комментировать
  • Почему Redux так популярен?

    bingo347
    @bingo347
    Crazy on performance...
    Он просто оказался первым подобным решением которое распиарили. И это реально решает.
    Просто у много кого уже есть проекты на нем написанные, это все надо поддерживать - вот и количество вакансий.
    А еще у многих, особенно у менагеров, есть стереотипы вроде "если за этим большая корпорация, то это будут поддерживать вечно" и "чем древнее инструмент - тем он стабильнее и надежнее".

    И да mobx удобнее и функциональнее. Просто по тому, что не может быть полезной библиотека на несколько килобайт, весь функционал которой пишется любым +/- способным разработчиком в максимум 50 строк кода. Хотя +/- способных разработчиков в веб-разработке очень мало, на фоне макак способных лишь приворачивать еще одну библиотеку к единственному фреймворку.
    Ответ написан
    Комментировать
  • Как отследить посещение пользователя?

    bingo347
    @bingo347 Куратор тега Node.js
    Crazy on performance...
    Потому что лайки - это не просто int счетчик в таблице статей, это отдельная таблица вида
    user_id | article_id | еще какие-то поля, вроде логов или еще что-то надо
    Первичным индексом у этой таблицы будет 2 поля - user_id и article_id
    И уже сама база не позволит одному юзеру поставить лайк 2 раза на 1 статью
    Ответ написан
    1 комментарий
  • Импорт модуля ради «побочных эффектов»?

    bingo347
    @bingo347 Куратор тега JavaScript
    Crazy on performance...
    Для начала стоит понять сам термин "побочный эффект".
    Вот Вы вызываете функцию, а она что-то делает за своими пределами, например пишет в файл или localStorage, или меняет Ваш DOM на странице, или меняет глобальные объекты. Это и есть побочные эффекты.
    Модуль тоже может иметь побочные эффекты. Например Вы можете не просто экспортировать некоторые функции из модуля, но и сразу что-то сделать, вне всяких функций.
    Например пусть у нас будет такой модуль:
    const div = document.body.appendChild(document.createElement('div'));
    
    export function remove() {
      document.body.removeChild(div);
    }
    Даже если мы просто импортируем его, но не вызываем функцию remove, он все равно произведет свой побочный эффект - добавит новый div в body. И это произойдет при первом встретившемся импорте.
    Нам в принципе может быть и не нужна функция remove (ее даже может и не быть), но нам нужен этот div в body - тогда можем просто сделать импорт как в Вашем примере и получить div в body в качестве результата.

    Конкретно в контексте вебпака и импортирования стилей, у Вас скорее всего будет включен в обработку или style-loader или MiniExtractCssPlugin.loader. Побочный эффект style-loader - добавление тега style со стилями из импортируемого css в head. А у MiniExtractCssPlugin.loader - побочный эффект - извлечение стилей в отдельный файл.
    Ответ написан
    1 комментарий
  • Как узнать из какого запроса пришло значение в LocalStorage?

    bingo347
    @bingo347
    Crazy on performance...
    Никак. LocalStorage не связан с запросами, он управляется чисто скриптами. И он не хранит информацию, о том кто и когда в него писал или читал из него. Все что хранится - это строки: ключ и значение
    Ответ написан
    Комментировать
  • Redux для "не React проектов"?

    bingo347
    @bingo347 Куратор тега JavaScript
    Crazy on performance...
    Правильным ли решением будет использовать redux для обычного веб-ресурса
    Почему бы и нет. Redux не имеет никакого отношения к React от слова совсем.

    Или есть альтернативы ?
    Ну можете взять обычный compose из lodash/ramda (в ramda кстати есть линзы, которые хорошо помогают работать с иммутабельными объектами) и соединить им Ваши "редьюсеры". Положить объект в переменную state в замыкании, и все - свой redux готов.
    Можно так же глянуть в сторону mobx или svelte/store если действительно хочется реактивности, а не тупого клонирования объектов
    Ответ написан
    Комментировать
  • Можно ли использовать Nodejs во Vue при написании программы на Electron?

    bingo347
    @bingo347 Куратор тега Node.js
    Crazy on performance...
    Можно. В том числе и без дополнительных пакетов.
    Нодовский require в render процессе есть так же в глобальном объекте (в window) и работает относительно html файла, с которым этот render процесс был запущен.
    Для вызова builtin модулей (всяких fs или самого electron) вообще пофиг, относительно чего работает require.
    В main процессе при создании render процесса (а так же для всех webview) нужно разрешить nodeintegration
    Ответ написан
    1 комментарий
  • Как работает websocket на низком уровне?

    bingo347
    @bingo347
    Crazy on performance...
    Вопрос 1
    Браузер инициирует новое tcp соединение на тот же 80 порт сервера или бывают случаи что на другой ?
    WebSocket работает не поверх голого tcp, а поверх http (а тот уже поверх tcp или tls -> tcp). 80 порт стандартный для http, а 443 - для https (http поверх tls). WebSocket по умолчанию использует те же 80 и 443 порты для ws и wss протоколов соответственно. Но никто не мешает использовать кастомный порт. Конкретные порты для конкретных протоколов - это не более соглашения. Порты работают на IP уровне, который ничего не знает о прикладном уровне.

    Вопрос 2
    Что сервер делает с ws пакетами - проксирует их к СП как есть в обертке, или же обертку раскрывает и передает "чистые/сырые" данные далее ?
    Если речь идет о nginx как о реверси прокси, то для него это обычный http запрос, просто клиент очень долго шлет тело запроса, а сервер тело ответа (главное таймауты тут выключить). Так как http в принципе не запрещает серверу начать слать ответ не закончив чтение запроса, все вполне прекрасно работает.

    Вопрос 3
    Как сервер отличает ws от http - по некой сигнатуре - типа по последовательности первых пришедших байт, по которым можно распознать что это именно ws а не http ?
    По http заголовкам. В частности клиент шлет заголовок upgrade в котором говорит, что хочет WebSocket и еще несколько специфичных для WebSocket заголовков, а сервер отвечает статусом 101 и своим набором заголовков. Это и есть WebSocket рукопожатие. Само общение происходит уже в теле запроса и теле ответа.

    Вопрос 4
    Как эти данные передаются в сторону СП - через переменные окружения, или через unix-socket или через tcp стек?
    Если используя последние два варианта, то получается что сервер держит внутри системы соединения с СП до тех пор пока "наружное" tcp соединение между клиентом и сервером не буде закрыто?
    На уровне tcp вообще пофиг сколько времени открыто соединение, какая из сторон в какой последовательности и сколько данных отправляет. Тут лишь то, что клиент может попробовать открыть соединение, сервер его может принять (или отклонить), а после любая из сторон может слать данные другой или закрыть соединение. Ну и плюс есть гарантии, что потерянные данные будут отправлены повторно и порядок получения совпадет с порядком отправки. На уровне http у нас обычный запрос-ответ, просто клиент слишком долго шлет тело запроса, а сервер - тело ответа. На уровне WebSocket у нас в обе стороны ходят MessageFrame'ы, содержащие данные + метаданные и имеющие четкие границы.

    Вопрос 5
    В свою очередь СП это отдельный unix процесс отличный от основного бекенд приложения, которое работает по принципу "спросили - запустился - обработал - сформировал ответ - отправил - завершился" Или же это все то же бекенд приложение только в том случае если с ним установлено ws-соединение, оно не прекращает свою работу?
    Как реализуете, так и будет. Но одно можно сказать точно, соединение должно быть открытым на протяжении всего сеанса обмена сообщениями.
    Важно еще понимать, что в контексте WebSocket нет понятий запрос и ответ (хотя их могут реализовывать нижележащие протоколы), есть лишь понятие сообщение. Каждая из сторон, пока открыто соединение, может в любой момент времени отправлять любое количество сообщений.

    P.S. если обе стороны (и клиент и сервер) не ограничены только http протоколом для общения через tcp (как например это происходит у браузерных приложений), то WebSocket будет лишней нагрузкой как на сеть, так и на вычисления. Лучше взять какой-нибудь бинарный сериализатор, с четкими границами (msgpack, flatbuffer) и гонять данные по raw tcp или tls.
    Ответ написан
    2 комментария
  • Как скрыть ссылку от индексации посредством скрипта?

    bingo347
    @bingo347 Куратор тега JavaScript
    Crazy on performance...
    скрыть ссылку от индексации посредством скрипта
    От поисковых роботов? Им вполне может быть пофик, как там скрипты DOM меняют, они вполне могут проиндексировать страницу как до выполнения скриптов, так и после.
    Если нужно запретить индексировать определенные страницы - для этого есть robots.txt - погуглите, уверен, что этот то что нужно.
    А еще советую подумать, а можно ли будет по Вашим импровизированным ссылкам ходить скринридером? А просто табом?
    Яндекс к сожалению еще до этого не допер, но вот гугл вполне может снизить Ваш сайт в выдаче за ухудшение a11y
    Ответ написан
    Комментировать
  • Как красиво записать присвоение на js?

    bingo347
    @bingo347 Куратор тега JavaScript
    Crazy on performance...
    ((req.query || (req.query = {})).where || (req.query.where = {})).profile = 1;

    или
    const {query = (req.query = {})} = req;
    const {where = (query.where = {})} = query;
    where.profile = 1;
    Ответ написан
    Комментировать
  • Как во Vue избавиться от .vue файла?

    bingo347
    @bingo347
    Crazy on performance...
    1. scss можно подключать из ts файла просто через import, в webpack скорее всего уже настроен необходимый лоадер. Со scoped конечно сложнее, но ИМХО scoped тормознутое зло, лучше css modules использовать, которые опять таки разруливаются через css-loader
    2. для шаблонов можно написать кастомный лоадер, который будет их компилировать, и можно будет просто заимпортить из ts
    import {render, staticRenderFns} from './messager.pug';
    и вставить как есть в компонент
    Сам ts файл и будет делать export default компонента
    3. для самого ts нужно будет описать declare module '*.pug' {} иdeclare module '*.scss' в каком нить .d.ts файле в корне проекта

    Вот только зачем? Вы лишаетесь HMR (хотя для шаблонов можно сделать в лоадере). Код компонента становится раскиданным по 3 файлам, что делает хуже его поддержку. Ну и другие разработчики явно Вас проклянут за такие костыли.
    Ответ написан
    Комментировать
  • Почему вылазит ошибка "Cannot read property 'authService' of undefined"?

    bingo347
    @bingo347 Куратор тега TypeScript
    Crazy on performance...
    https://gist.github.com/wuzzabi/9094585b852292058d...
    вот здесь Вы потеряли контекст
    Ответ написан
    Комментировать
  • Как организовать асинхронную функцию .map?

    bingo347
    @bingo347 Куратор тега JavaScript
    Crazy on performance...
    let rawNews = []; // Массив объектов (Свеженькие новости прямо из БД)
    let rawCats = []; // Массив объектов с обработанными новостями
    // Промис с массивом результатов
    let modifyNews = Promise.all(rawNews.map(async (item, i, arr) => {
        item.autor = await getUserByID(item.autor); // Асинхронная функция которая выставляет имя автора вместо id
        return item;
    }));
    Ответ написан
    1 комментарий
  • Как сделать диагональный scroll?

    bingo347
    @bingo347 Куратор тега JavaScript
    Crazy on performance...