• Возможно ли задать timeout для fetch?

    ruddy22
    @ruddy22
    Спасение утопающих — дело рук самих утопающих
    Самый простой вариант
    const get = timeout => url => 
      Promise.race([
        fetch(url),
        new Promise((resolve, reject) =>
          setTimeout(() => reject(new Error('timeout')), timeout)
        )
      ]);

    Вариант с AbortController
    Ответ написан
    4 комментария
  • Какие материалы считаются лучшими для глубоко изучения JS?

    @dmitry-toster
    Для глубоко изучения JS

    Вряд ли есть что-то лучше серии книг Kyle Simpson - You don't know JS, где одной только теме про thisили замыканию уделена целая книга

    Интересен супер подробный разбор event loop

    Помимо книг выше, есть также отличное видео на YouTube после которого отпадут все вопросы как оно работает

    Что можно считать лучшим источником

    Собственно Standard ECMA-262
    Ответ написан
    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 комментария
  • Что быстрее массив или объект?

    Мне это напомнило историю, когда некий докладчик сравнил поиск в Яндексе и прямое указание сайта в адресной строке. Типа, когда он пишет адрес сайта, то сразу переходит на него, и якобы поиск не включается. Однако даже при прямом указании адреса сайта всё равно включается поиск: вы ввели адрес сайта, но это не точный путь к серверу, где хранятся данные. Пока идёт запрос к данным, и пока они идут обратно, включаются несколько поисков на разных этапах.

    Так же и здесь. По сути системе нужно достать некое значение из памяти. Массивы изначально заточены под машинную организацию памяти: по порядку. Логично предположить, что если вам нужно N-e значение, то оно быстрее достанется из памяти, так как оно N-e в самой памяти, начиная от некой ячейки (грубо говоря). Более сложные ассоциативные массивы (или объекты) организованы в памяти более сложно (извиняюсь за тавтологию). Ассоциативный массив - это, как минимум, два обычных массива. Соответственно, выполняя поиск по нему, работают уже минимум два поиска.

    это всегда перебор всего массива каждый раз.

    Если ключи уникальны, а в обычных javascript массивах это так, то вряд ли поиск продолжается после нахождения нужного элемента.

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

    По существу вопроса, мне кажется, вы всё делаете совершенно правильно, потому что в вебе самое главное - это удобство постоянного развития проекта. Если код внешне, и по логике похож на то, как данные организованы в бытовом восприятии, это удобно: быстро вникаешь и можно дорабатывать.
    Ответ написан
    Комментировать
  • Как делается backend на Java?

    sergey-gornostaev
    @sergey-gornostaev Куратор тега Java
    Седой и строгий
    Выбирайте PHP. Месяца не хватит даже на изучение материала.
    Ответ написан
    5 комментариев
  • Выбор фреймворка для нового проекта - Angular? React? Vue?

    dom1n1k
    @dom1n1k
    Лично для меня Vue - это такой "фреймворк с человеческим лицом".
    В целом JS-мир похож на поле боевых действий, где постоянно то налеты авиации, то кононада гремит, то хипстерская конница с новым логотипом на знамёнах проскачет.
    А "обычный" человек сидит в подвале, обхватив голову руками, и думает - мама дорогая, куда я попал, и чё ваще вокруг происходит?
    Какие-то новые паттерны, подходы, языки... Раньше, чтобы начать, достаточно было блокнота и браузера. Пишешь hello world и сразу его видишь. Теперь нужно поставить ноду, овер 9000 пакетов, десять транспиляторов, таск-менеджеров и бандлеров. Пока увидишь рабочий результат - поседеешь.
    И вдруг какая-то добрая душа взяла у хипстоты всё самое лучшее и разумное, что та родила, но очистив от лишних абстракций и усложнений - и выкатила велосипед в виде велосипеда, а не турбо-космолета с инструкцией толщиной как "Капитал". И снова можно писать в блокноте и смотреть в браузере. При этом почти не проигрывая в возможностях.
    Ответ написан
    1 комментарий
  • Полезны ли курсы от "Специалиста"?

    Если всё таки хотите скринкасты, то вот ---> 0% воды Art Sorax
    Ответ написан
    2 комментария
  • Как составить план самообразования на ближайший год?

    @dchuvasov
    "Чтобы научиться программировать нужно программировать."

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

    Лично для меня поставить себе самому задачу очень проблематично, поэтому я просто лазил по фриланссайтам и искал задачи.

    Ты же можешь, просто найти несколько сайтов которые считаешь "качественными и адаптивными" и реализовать их сам. Если у тебя совсем нет опыта в этом, то возьми пару популярных книг по дизайну и верстке и почитай их. А когда будет примерное представление как надо делать, то тут уже гугл в помощь. Ну и поиск всяких best practies.

    ну и вот можно почитать статью theasder.github.io/learning/2015/01/25/let-us-lear...
    Ответ написан
    1 комментарий
  • Как быстро подтянуть свой уровень веб-разработчика, чтобы соотвествовать требованиям работодателей?

    @spamerbo
    Приветствую!
    Был в Вашей ситуации год назад примерно.
    Изучайте javascript, чистый, на хорошем уровне. Все остальное тлен - изучаются за несколько дней при реальной работе и jQuery, и bootstrap, git и т.д.
    Не слушайте советов начинать с jQuery - это путь в быдлокодство без хорошего знания js. Туда же и фриланс, там не будет повода развиваться.
    Учите javascript, работу с DOM, соглашайтесь на тестовые задания от работодателей. Далее сложная цель устроиться на первую свою работу, не теряйте время на веб-студии, сейчас в тренде SPA - научиться backbone, angularJS намного проще на реальном проекте. Через полгода такого опыта вы будете востребованным специалистом с хорошей зарплатой. Удачи!
    Ответ написан
    6 комментариев