Задать вопрос
  • Как работает get и set в computed?

    bingo347
    @bingo347
    Crazy on performance...
    Это не геттер и сеттер без имени, это методы с именами get и set.
    Ответ написан
    Комментировать
  • Выполнить функцию когда скролл на нужной позиции?

    bingo347
    @bingo347 Куратор тега JavaScript
    Crazy on performance...
    Комментировать
  • Как сравнить дату с датой из объекта?

    bingo347
    @bingo347 Куратор тега JavaScript
    Crazy on performance...
    Дату в объекте нужно распарсить в объект Date
    Сами даты приводятся операторами сравнения к числу (unix timestamp в милисекундах) и вполне себе сравниваются:
    const date = new Date('02-10-2005'); // это лучше вынести за цикл, что бы не делать много раз одно и то же
    for (card of json.CardInfo) {
       if(new Date(card.Date) < date) {
        console.log('true');
      } else{
        console.log('false');
      }
    }

    P.S. вообще конструкций вида if(...) { true } else { false } лучше избегать
    for (card of json.CardInfo) {
        console.log(String(new Date(card.Date) < date));
    }
    этот пример отработает абсолютно аналогично предыдущему, но читать кода тут меньше
    Ответ написан
    7 комментариев
  • Стоит ли учить С/С++ если не планируешь писать на нём?

    bingo347
    @bingo347
    Crazy on performance...
    Языки не нужно учить. Это крайне вредно. Ну заучите Вы синтаксис и базовые принципы, а что дальше? Программировать с этим Вы не сможете. Подход выучить ЯП Х не работает, как и не работает подход выучить естественный. Просто подумайте, кто быстрее заговорит на английском - тот кто выучит много слов и правил или тот кто поедет в США и будет вынужден там общаться? С языками программирования все то же самое.

    Теперь о C и C++
    C наверно самый простой ЯП, проще только ассемблер. Из высокоуровневых абстракций в нем только типы данных да структурное программирование (if, for, while, ...). Вы скорее всего уже с этим всем знакомы. Из нового разве что будет работа с указателями, опять же максимально простым способом - в лоб.
    C++ - обвешали простой C максимальным количеством высокоуровневых абстракций (все виды полиморфизма, ООП, замыкания, динамическая диспетчеризация и т.д.), что сделало его очень сложным. Вам понадобятся годы практики (практики, а не зубрежки!), чтобы просто понять, что здесь происходит. А скорее всего Вы просто бросите это дело, породив пару десятков UB в простейшей программе и на ровном месте.
    Ответ написан
    Комментировать
  • Какой самый низкоуровневый язык програмирования?

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

    P.S. когда уже русский язык станет самым популярным? Как Вы собираетесь с формальными языками разбираться, если не можете освоить естественный?
    Ответ написан
    1 комментарий
  • Как работает сборщик мусор с колбеками Promise?

    bingo347
    @bingo347 Куратор тега JavaScript
    Crazy on performance...
    Сборщики мусора (далее GC) бывают разные, в том же v8 используется сразу 3 типа GC в зависимости от поколения объектов (упрощенно молодое, старое и сложные случаи), но в большинстве своем принцип работы сводится к просчету достижимости из некоторого корня в дереве объектов (например глобального объекта, но не только его). v8 не является исключением, и его GC содержит C++ api для создания таких корней. Из JS мы данным api можем воспользоваться лишь косвенно, через сущности языка предоставляемые либо самим v8 либо платформой (браузером, node.js, deno и т.д.)
    Чтоб было понятно давайте рассмотрим простой пример:
    const h = 'Hello world!';
    const n = 'nothing';
    setTimeout(() => {
      console.log(h);
    }, 1000);
    У нас есть строковые переменные h и n. Переменная n нигде больше не используется и ее память очистится при ближайшей работе GC. А вот переменная h оказалась в замыкании созданном стрелочной функцией. И хотя в JS мы не можем достучаться до h имея ссылку на эту функцию, сама функция все таки имеет ссылку на h, а значит h не может быть уничтожена пока не будет уничтожена сама функция. В терминах GC ссылка на h будет серой, то есть сама ссылка на h недоступна из корня напрямую, но сейчас мы проверяем объекты, которые на нее ссылаются и истина будет зависеть от них (подробнее можете погуглить "mark black white and gray memory in gc").
    Давайте посмотрим на саму стрелочную функцию, которая держит h в замыкании. Из кода видно, что мы ее передаем в функцию setTimeout, о которой известно, что это api предоставленное платформой (а значит вероятно какая-то часть написана на C++), а так же, что она асинхронная. Платформе реализующей setTimeout наша функция понадобится после асинхронного ожидания и никто платформе не сможет гарантировать, что во время этого ожидания не будет работы GC, поэтому ей ничего не остается, кроме как запросить у v8 создание нового корневого дерева объектов, в которое и будет положена ссылка на данную функцию.
    После же выполнения таймаута платформе больше не нужна наша функция, поэтому ссылка на нее будет удалена из дерева объектов. А так как других ссылок на функцию нет, и она больше не доступна ни из одного корня - GC удалит из памяти и функцию и строку связанную h, которая так же стала недоступна из корня.

    Посмотрим на пример из вопроса. У нас есть стрелочная функция, которая удерживает на себе инстанс компонента через this ссылку (так как стрелочные функции замыкают this). Саму функцию в памяти удерживает промис порожденный вызовом loader('url'), так как мы отдали её в метод then. Других ссылок на данную функцию нет, а значит и сама функция и ее замыкание (инстанс компонента) будут "жить" не менее "жизни" промиса.
    Скажем был отправлен запрос на сервер, но потом компонент в котором был объявлен промис и колбек был удален.
    И после удаления приходит ответ от сервера, и он выполнит колбек. Это значит что колбек остался в памяти со всеми переменными контекста
    Если других ссылок не осталось, то инстанс компонента будет удерживаться от очистки через промис.

    Теперь стоит разобраться с самим промисом. У него может быть 3 состояния - pending, resolved или rejected. После перехода в состояния resolved или rejected промис может выполнить сохраненные колбэки в ближайшем микротаске, а после он удалит на них ссылки из себя, в следствии чего, память удерживаемая замыканием колбэка может быть очищена (при отсутствии на нее других ссылок, достижимых из какого-либо корня).
    В состоянии pending промис может потенциально находится бесконечно долго, при этом ссылаясь на все колбэки переданные ему в методы then, catch или finally, а значит так же косвенно ссылаясь на их замыкания. И тут все зависит от того, кто ссылается на данный промис, и достижим ли он из корня. И да, промис вполне может быть удален из памяти так и не дождавшись своего завершения.
    интересное умозаключение
    Если Promise - это обещание, то в данном случае оно будет нарушено?


    В комментах к вопросу есть еще один интересный пример:
    function getSomething(){
      return new Promise((resolve, reject)=>{
        if(sys_condition){
           resolve();
        } 
      })
    }
    
    function testPromise(){
      let config = {....}
      getSomething().then(()=>{
         #use config
         goOn(...config)
      })
    }
    
    testPromise();
    У нас есть вызванная 1 раз функция testPromise, которая получает из функции getSomething промис, в который с помощью метода then сохраняет колбэк, удерживающий в замыкании переменную config. Сам промис она нигде не сохраняет, что здесь очень важно.
    В функции getSomething мы просто возвращаем промис созданный через его конструктор, который как мы уже знаем нигде больше не сохраняется. И на этом могло бы все и закончится, без вызова колбэка независимо ни от чего. Но конструктор промиса выполняет свой колбэк синхронно, а кроме того он передает в него 2 функции - resolve и reject, которые в своем замыкании ссылаются на только что созданный промис (а это уже 2 ссылки на него, хотя мы то его никуда не сохраняли). Переменная reject никак не используется, а значит спокойно может быть удалена после завершения колбэка. Переменная resolve просто вызывается как функция внутри условия, но более тоже никак не используется и никуда не сохраняется, а значит так же может быть удалена.
    В этом примере. если sys_condition = false и resolve не вызовется, это значит что создается утечка памяти
    Нет, утечки памяти не будет. Колбэк созданный в testPromise будет удален вместе с замыканием, так и не вызвавшись ни разу.
    Ответ написан
    3 комментария
  • Как отсортировать объект по вложенному массиву?

    bingo347
    @bingo347 Куратор тега JavaScript
    Crazy on performance...
    const newArray = arr.slice(); // так как sort мутирует массив, а нужен новый
    const isAnnaSkill = skill => skill.name === 'Anna';
    const getAnnaLevel = item => item.skills.find(isAnnaSkill)?.level;
    newArray.sort((a, b) => getAnnaLevel(b) - getAnnaLevel(a));
    Ответ написан
    2 комментария
  • Как обработать 2 запроса одновременно в node.js?

    bingo347
    @bingo347 Куратор тега Node.js
    Crazy on performance...
    Комментировать
  • Как прокачать навыки функционального программирования?

    bingo347
    @bingo347 Куратор тега JavaScript
    Crazy on performance...
    Я бы начал с изучения книги Луиса Атенсио "Функциональное программирование на ...
    Дальше можно изучить серию статей "Мышление в стиле Ramda" на хабре
    Ответ написан
    Комментировать
  • Как узнать какой global user.name и global user.email и как переключиться на старом акаунте гитхаба?

    bingo347
    @bingo347
    Crazy on performance...
    git config --global --get user.name
    git config --global --get user.email

    С аккаунтом github это никак не связано, все хранится локально у Вас на компе

    Глобальные конфиги лежат в файле $HOME/.gitconfig
    Локальные - в ближайшей папке .git вверх по дереву
    Ответ написан
    Комментировать
  • Что следует почитать/посмотреть для изучения Git?

    bingo347
    @bingo347
    Crazy on performance...
    Ответ написан
    Комментировать
  • Как посчитать количество повторений символов в строке?

    bingo347
    @bingo347 Куратор тега JavaScript
    Crazy on performance...
    Воспользуйтесь для подсчета символов обычным объектом, где ключи - буквы, а значения - их количество, а уже потом сформируйте из него массив.
    Ответ написан
    Комментировать
  • Как отфильтровать массив?

    bingo347
    @bingo347 Куратор тега JavaScript
    Crazy on performance...
    То что у Вас в полях created и viewed вполне можно отдать в конструктор Date, а даты уже можно сравнивать между собой
    console.log(new Date("2020-05-22 16:24:16")); // работает

    Дальше, последний created, тут нужно уточнение:
    Если массив messages всегда упорядочен по полю created, как и в примере, то можно просто брать последний элемент массива и работать с ним:
    const lastMessage = messages[messages.length - 1];
    console.log(lastMessage);

    Если такой гарантии нет, то нужно искать максимум:
    const lastMessage = messages.reduce(([maxDate, maxMessage], currentMassage) => {
      const currentDate = new Date(currentMassage.created);
      if(currentDate > maxDate) {
        return [currentDate, currentMassage];
      }
      return [maxDate, maxMessage];
    }, [-Infinity, null])[1];
    console.log(lastMessage);

    Ну а если с этим разберетесь, то с последним пунктом у Вас уже не должно быть проблем, тут все аналогично
    Ответ написан
    3 комментария
  • Map это объект или массив?

    bingo347
    @bingo347 Куратор тега JavaScript
    Crazy on performance...
    В js все объект, что не является примитивом (простые объекты, экземпляры классов, массивы, Map, Set, функции).
    Так что да, Map это объект.
    А вот массивом он не является, ибоArray.isArray(new Map()) // false
    Здесь есть вот такая штука [[Entries]]. А entries возвращает массив свойств объекта
    Вообще-то entries возвращает итератор. Итератор - это тоже не массив.
    Ответ написан
    2 комментария
  • Полноэкранный режим на сайте?

    bingo347
    @bingo347 Куратор тега JavaScript
    Crazy on performance...
    Проблема в том, что при переходе по ссылке документ, на котором вызван фулскрин, перестает существовать, а вместо него формируется новый, и при этом происходит выход из фулскрина.
    Решения тут я вижу два:
    1. Костыльное. Кроме документа фулскринить еще можно video и iframe, и iframe может тут помочь, так как он останется неизменным, сколько бы страниц в него не загружалось.
    2. Сложное. Можно переделать сайт в SPA, тогда настоящих переходов не будет, и все страницы будут работать в пространстве одного документа
    Ответ написан
  • Есть ли эффект-анимация перелистывания страниц книги со сменой url?

    bingo347
    @bingo347 Куратор тега JavaScript
    Crazy on performance...
    А заглянуть как у них сделано?
    Вся магия тут: megaweb.su/demo/css3_book/css/style.css
    Ответ написан
  • Как разобрать HTTP запрос?

    bingo347
    @bingo347
    Crazy on performance...
    Что делать если размер запроса больше чем размер буфера?
    Читать в цикле. read вообще не гарантирует, что заполнит буфер полностью, но больше его размера он точно за раз не прочитает. А еще он возвращает io::Result<usize>, в котором сообщает, сколько реально байт было прочитано.
    1.1) Нужно будет читать пока не найдется CRLF в буфере ?
    Пока read не вернет Ok(0), ну или ошибку. Хотя с ошибкой не все так однозначно, согласно доке может вылететь Err(io::ErrorKind::Interrupted) при котором стоит повторить попытку чтения. Вообще CRLF будет после каждого заголовка, а когда заголовки закончатся будет 2 CRLF подряд, а потом еще может быть тело запроса, а может и не быть.
    1.2) для этого мне нужно пройтись по буферу и искать CRLF . если его нет то очистить буфер и продолжать читать ?
    нет, нужно распарсить то что пришло, куда-то сохранить, а потом продолжить чтение.
    2) Как отделять один http запрос от другого ?
    Если у нас не keep-alive, то каждый запрос будет в отдельном соединении, но keep-alive наступает только если обе стороны прислали заголовок Connection: keep-alive Можете сделать по простому, и отвечать с заголовком Connection: close, все равно в учебном проекте производительность у Вас будет никакая. Но если хотите все же заморочиться, то правило тоже не сложное - следующий запрос начинается в следующем же байте, где закончился текущий. Размер тела запроса в байтах можно узнать из заголовка Content-Length, а если его нет, то можете считать, что его значение 0.

    Что следует почитать для Вашей задумки:
    1. Спеку http
    2. Исходники hyper
    3. Исходники actix-web
    Ответ написан
    Комментировать
  • TS React children state?

    bingo347
    @bingo347 Куратор тега TypeScript
    Crazy on performance...
    Или нормально типизировать эту функцию (зачем Вам вообще ts, если Вы пишите any?) ну или заткнуть в тип стейта поле вида[k: any]: any
    Ответ написан
  • Не копируется массив, в чем причина?

    bingo347
    @bingo347 Куратор тега JavaScript
    Crazy on performance...
    Не копируется, потому-что внутри массива maze у Вас лежат ссылки на подмассивы, и Вы копируете лишь их, а не сами массивы.
    Придется скопировать на уровень глубже:const mazeCopy = maze.map(sub => sub.slice())
    Ответ написан
    Комментировать