• Почему разрешается добавить значение в кортеж?

    bingo347
    @bingo347 Куратор тега TypeScript
    Crazy on performance...
    Потому что кортеж в ts это подтип массива, а система типов ts настолько убога, что через нее нельзя выразить, что у подтипа недоступны какие-то методы основного типа.
    qwe[2] = 77
    Тут просто сразу 2 ошибки типов:
    во-первых 77 нельзя присвоить типу undefined - так как [string, number] - это вполне себе сахар над типом
    {readonly length: 2; 0: string; 1: number} & Readonly<typeof Array.prototype>

    во-вторых 2 в индексе опять таки нельзя воткнуть в тип 'length' | 0 | 1 | keyof typeof Array.prototype
    Ответ написан
    Комментировать
  • В git закоммитил в master - как исправить?

    bingo347
    @bingo347
    Crazy on performance...
    # переименуем master в experiment
    git checkout master
    git branch -m experiment
    # удалим удаленный master
    git push --delete origin master
    # зальем текущую ветку на удаленный репо:
    git push -u origin experiment
    # переключимся на комит с которого пойдет мастер по его хэшу:
    git checkout 3624ce5
    # ответвимся от сюда в новую ветку с именем master
    git checkout -b master
    # и залем ее на удаленный репо
    git push -u origin master
    Ответ написан
    4 комментария
  • Как передать метод класса в worker_theards node.js?

    bingo347
    @bingo347 Куратор тега Node.js
    Crazy on performance...
    Потому что функции не являются сериализуемым объектом
    Если что, сериализуется этим: https://nodejs.org/docs/latest-v12.x/api/v8.html#v...
    Вы можете послать сообщение, а метод поток должен вызывать сам
    Ответ написан
  • Почему XOR 0 убирает дробную часть числа?

    bingo347
    @bingo347 Куратор тега JavaScript
    Crazy on performance...
    Почему число получается целым, уже объяснил Stranger in the Q
    Я же постараюсь объяснить, как это работает, и почему оно не лучше Math.floor:
    В js тип number представлен числами двойной точности по стандарту кодирования IEEE 754, а это значит, что 53 бита выделяются под значимую часть (старший бит - бит знака, если 1 - то число отрицательное) и 11 бит под экспоненту (старший бит опять же бит знака), всего выходит 64 бита. Притом данный стандарт позволяет абсолютно точно работать с целыми числами до ±252 и поэтому до не давнего времени в js честного int не было.
    Теперь к бинарным (не нравится мне перевод "побитовый") операциям, как известно "исключающее или" (xor, ^) с нулем, а так же "или" (or, |) с нулем не меняют число, возвращая другой операнд в неизменном виде. Но тут вклинивается стандарт js и говорит, что бинарные операции выполняются над signed int32 представлением числа и при представлении можно просто отбросить все лишнее, что движки и делают.
    Как отбросить все лишние? Да просто, движок js прекрасно знает, в какой части числа расположена значимая часть, он просто берет младшие 32 бита значимой части и кладет их в int32 контейнер ну и еще переносит бит знака на свое место. Обратное преобразование похоже - в нулевой float64 контейнер раскладываем: старший бит (знак) на свое место, остальные 31 бит - на свое.

    А теперь давайте поэкспериментируем в обычной браузерной консоли:
    Math.floor(1.1) // 1
    parseInt(1.1) // 1
    1.1 | 0 // 1
    1.1 ^ 0 // 1 - как уже писал выше, эффект будет 1 в 1, как и с |
    
    // пока все было ок, но как насчет отрицательных чисел?
    Math.floor(-1.1) // -2 - округляем в сторону -Infinity
    parseInt(-1.1) // -1 - отбрасываем экспоненту
    -1.1 | 0 // -1 - отбрасываем экспоненту и не только (но тут не имеет значения пока)
    
    // попробуем с чем-нибудь побольше
    2 ** 31 // 2147483648
    2147483648 | 0 // -2147483648
    /*
    не зная как преобразовывается число выше, это было бы не очевидно
    но смотрим выше "он просто берет младшие 32 бита значимой части и кладет их в int32 контейнер"
    2 ** 31 в двоичном виде - это единичка и 31 нолик
    и эта единичка попала в бит знака при переноси в int32
    тем самым мы получили самое маленькое число в int32
    */
    
    // давайте еще пример, набью как я большое число от балды:
    34646456436346346212424 // 3.464645643634635e+22
    34646456436346346212424 | 0 // 1178599424
    /*
    ну в первом примере мы видим интересную особенность чисел с плавающей запятой
    мы можем хранить не только дробные числа, но и очень большие целые, правда с потерей точности
    e+22 - это и есть экспонента, это значит число до e нужно умножить на основание системы счисления (10) в степени +22
    а при бинарной операции эта экспонента отбрасывается, как и старшие биты значимой части
    в 32 младших битах осталось 1178599424
    забавно, что я случайно вбил такое число, у которого 32 бит содержал 0 (шансы были 50/50)
    если бы там оказалась 1, то я бы вновь получил отрицательное число
    */
    Ответ написан
    Комментировать
  • Vue.js для мультистраничных приложений с webpack?

    bingo347
    @bingo347
    Crazy on performance...
    Можно.
    Самое простое - посмотреть в сторону nuxt и его generate
    Но если не устраивает, то можно заморочиться и самому сделать сборку под конкретные цели
    Ответ написан
    Комментировать
  • Возможна ли прокачка алгоритмов без хорошего знания синтаксиса?

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

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

    Интересно тут несколько вещей:
    1. ребенок не задает таких вопросов, он просто начинает говорить, и говорит еще и еще, пока это не начнет получаться хорошо.
    2. хотя мой внутренний ru-lint зацепился за отсутствующую запятую, это не помешало понять мне заложенный Вами в текст смысл. Компьютеры в большинстве случаев так не могут, будет ошибка компиляции.
    3. я здесь привожу в аналогию русский язык и делаю это так же используя русский язык, но мои знания в нем не совершенны, вполне возможно, что в данном тексте и я где-то неосознанно допустил ошибку, но смысл от этого сохранился

    Ну и как заметили выше, алгоритмы это не только про программирование и они никак не привязаны к конкретному ЯП.
    Ответ написан
    Комментировать
  • Настройка webpack для MPA?

    bingo347
    @bingo347
    Crazy on performance...
    1) Отдельно собирать scss файлы из точки входа index.scss
    Примерно такой конфиг:
    const path = require('path');
    const MiniCssExtractPlugin = require('mini-css-extract-plugin');
    
    module.exports = {
      entry: path.join(__dirname, 'src/styles/entry.scss'),
      output: {
        filename: 'drop-it.js', // от js артефакта никуда не деться, но файл по сути будет пустой
        path: path.join(__dirname, 'dist')
      },
      module: {
        rules: [{
          test: /\.scss$/,
          use: [MiniCssExtractPlugin.loader, 'css-loader', 'sass-loader']
        }]
      },
      plugins: [new MiniCssExtractPlugin({
        filename: 'styles.css'
      })]
    };


    Отдельно собирать ts файлы из точки входа index.ts
    да без проблем, опять таки нужен будет ts-loader. Ну и скажу свое ИМХО тут, что транспайлинг лучше не доверять тайпскрипту, а подключить бабель с пресетом env
    ну и не забыть настроить как для бабеля так и в ts-config, что выходные модули должны быть ES, иначе останетесь без тришейкинга.

    Отдельно проходиться по всем html файлам из папки src/html и складывать их в /output/
    с этим уже по заморочнее будет
    Для импортов думаю нужен какой то препроцессор будет, ща с ходу и не соображу, чем можно, сам разве что на handlebars такое делал
    Для обработки вебпаком можно взять это https://webpack.js.org/loaders/html-loader/
    Для подключения всех файлов из папки по образцу можно использовать https://webpack.js.org/api/module-methods/#require...
    ну и еще нужно будет как то извлечь все в отдельные файлы, хотя я лично бы не парился с поиском готовых решений, а просто воткнул бы свой лоадер и в нем бы писал все в файл
    Ответ написан
    1 комментарий
  • Как переделать из нативных переменных?

    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 если действительно хочется реактивности, а не тупого клонирования объектов
    Ответ написан
    Комментировать