Ответы пользователя по тегу JavaScript
  • Как работают колбэки в js?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    Как вы уже поняли и верно заметили, коллбэк это функция, которую передали куда-то и вызовут, когда надо будет.

    Асинхронность достигается не за счёт коллбэков. Их просто удобно использовать там, где есть асинхронность. Хотя ещё удобнее промисы.

    Асинхронность возникает там, где рвётся последовательный (строчка за строчкой) порядок выполнения кода. Где один код уже отыграл и отпустил движок JS – пусть остынет, нет пока больше дел. А остались навешанные слушатели событий, таймеры, нерешённые промисы, долгоиграющие ajax-запросы и прочая асинхрота.

    В эти слушатели, таймауты и прочие и передают в коллбэке те строки кода, которые надо будет выполнить «потом».

    Пример. Не хотите setTimeout, тогда с кнопкой пробела:
    function superCallback() {
      console.log("Свершилось! Коллбэк сработал.");
    }
    
    document.addEventListener("keydown", superCallback);
    // на этот момент мы объявили функцию и повесили слушатель события
    // дальше всё, делать больше нечего, движок JS свободен
    // но слушатель сидит, ждёт.
    Наступает ночь асинхронность. Никакой код сейчас не работает. Но заряжен слушатель с коллбэком.

    Теперь, если выждав паузу, нажать какую-нибудь клавишу, сработает слушатель и проиграет вслух код в коллбэке.
    Ответ написан
  • Как разбить массив на подмассивы?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    const repack = arr => {
      const result = [...new Array(1 + Math.floor((arr.length - 1) / 2.5))].map(() => []);
      arr.forEach((el, i) => result[Math.floor(i / 2.5)].push(el));
      return result;
    }
    
    JSON.stringify(repack([1, 2, 3, 4, 5, 6, 7, 8, 9]))
    // "[[1,2,3],[4,5],[6,7,8],[9]]"


    Здесь несколько моментов, которые ещё пригодятся в других задачах:
    1. Создание массива нужно длины с заполнением начальными значениями
      [...new Array(length)].fill(value) // тут не годится, т.к. заполняем пустыми массивами
      // и чтобы это не был один и тот же массив («передача по ссылке»)
      // заполняем другим способом, через map()
      [...new Array(length)].map(() => [])
    2. получение чередующегося ряда 3, 2, 3, 2, ... через Math.floor(i / 2.5)
    Ответ написан
    Комментировать
  • Как сделать функцию превращающую координаты в градусы?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    5e6b3fcd2f829159766480.png

    Надеюсь, иллюстрация вашей задачи поможет сориентироваться.
    На схеме A, B, C, D – данные 4 точки.
    E — пятая точка, с нахождением (X, Y) которой у вас пятая точка.

    Тригонометрия, школьная программа. OE = 5. Угол AOE = 100°
    Надо найти OF и OG
    OF = OE * cos(a)
    OG = OE * sin(a)
    Ответ написан
    6 комментариев
  • Получение индекса в js?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    for(let p0 in obj) {
        for (let p1 in obj[p0]) {
            console.log(p0, p1);
        }
    }
    //   0 0
    //   1 0
    //   2 0
    //   2 1
    //   3 0
    Ответ написан
    Комментировать
  • Почему не получается сгенерировать 20 значный код?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    Можно сгенерить 20 случайных символов
    [...new Array(20)].map(
      () => Math.round(0xF * Math.random())
        .toString(16)
        .toUpperCase()
    ).join('')


    Ответ написан
    6 комментариев
  • Можно ли использовать в названии переменной другую переменную?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    Заведите для них общий контейнер. Массив или объект:
    const container = {};
    
    for (let i = 0; i < 10; i++) {
      const id = `#player${i}`;
      container[id] = new Player(id);
    }
    Ответ написан
  • Как получить файл из строки?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    Попробуйте дописать перед строкой data:image/jpeg;base64,

    <img src="data:image/jpeg;base64,/9j/4AAQ..." />

    См. Data URL
    Ответ написан
    1 комментарий
  • Как отличить сферическую панораму от простой?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    не факт, что это предусмотрено стандартом — подстрока "panoram" там не встречается.

    Google описывает свой стандарт XMP для сферических изображений Street View, где не предусматривает циллиндрической проекции, только сферическую.
    Ответ написан
    2 комментария
  • Что нужно уметь делать и знать в JavaScript чтобы переходить к изучению Vue.js?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    Вероятно, не стоит держать строгую последовательность «сначала такие темы по JS, только затем Vue».

    Начните с простых примеров использования Vue. По мере возникновения вопросов «а это что за ... такое?» закрывайте пробелы в JS.
    Ответ написан
    1 комментарий
  • Зачем нужен then в промисах если есть await?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    «Вначале были промисы»
    Затем, позже, сделали разноцветный синтаксический фантик для них — async / await

    У промисов держателем кнопки «пауза» являтся очередной промис. У этого промиса, как будильника, можно вызвать метод then() — как приклеить стикер на циферблат, где написано, что надо будет сделать, когда время придёт.
    В приклеенный метод then() ничего не попадает «сразу». Вернее, в него сразу передают 2 функции: одну вызовут, когда промис выполнится; вторую – если обломается: .then(onResolve, onError)
    Стоит будильник, на нём наклейка then, на ней написано, что сделать, если ОК и если облом. Ждём-с. Тикает.

    await прячет под капот движка JS лишние провода, и наверху просто возвращает результат выполненной асинхроты. Или кидает Exception в случае облома — его надо ловить обычными try..catch

    Перечитав вопрос, предположу, что неправильно готовили промис с запросом. Надо примерно так:
    const requestPromise = new Promise(function(res, rej) {
      setTimeout( function(result){ // имитация асинхр запроса куда-то
        // тут, типа, наконец получили ответ
        if (result.error_code) {
          rej(error_code); // облом
        } else {
          res(result); // обещание выполнено с результатом
        }
      }, 2000);
    });
    
    // здесь requestPromise – это Promise в статусе "pending"
    
    requestPromise.then( // сюда ничего не попадает «сразу». Оно внутри ждёт. Терпеливо.
      function(result) {console.log(result, "мы молодцы");},
      function(error) {console.error(error, "облом вышел");},
    );
    При желании можно навесить ещё собак then'ов на тот же Promise:
    requestPromise.then(r => console.log("result log:", r));
    Ответ написан
    Комментировать
  • Почему столкновение работает неправильно?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    Проблема в этой строке:
    collision(enemy[i].x,enemy[i].y,player[j].x,player[j].y,32,32,32,32,player.splice(j,1),enemy.splice(i,1));
    В функцию передаётся не действие, которое надо выполнить в случае — а его результат. Вот эти
    player.splice(j,1)
    enemy.splice(i,1)
    выполняются сразу, при первом же обращении — и не останется ни игроков ни врагов. Ядерная зима.

    Чтобы не выполнять их сразу же, оберните эти действия в функцию и передавайте функцию в collision(), чтобы там её вызвали только после проверки условий.

    Ещё можно не передавать сотню параметров, а договориться, что у объектов игроков и врагов всегда будут свойства
    x, y, w, h. Так можно передавать сами объекты целиком:
    function collision(A, B, onCollision) {
      if (
        A.x + A.w >= B.x 
        && A.x <= B.x + B.w
        && A.y + A.h >= B.y
        && A.y <= B.y + B.h
      ) { 
        onCollision(); // <-- только тут выполнятся действия
      }
    }
    
    // ...
    player.push({x: 0, y: 0, w: 32, h: 32});
    enemy.push({x: 144, y: 104, w: 32, h: 32});
    // ...
    collision(
      enemy[i],
      player[j],
      function() {
        player.splice(j,1);
        enemy.splice(i,1);
      }
    );

    Рабочий jsFiddle
    Ответ написан
    9 комментариев
  • Могу ли я согнуть блок div с его содержимым с помощью js?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    Был похожий вопрос, Как сверстать текст по дуге?
    там я сделал пример похожего искажения:
    example.png

    github
    Ответ написан
    Комментировать
  • Добавить +1 к .index()?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    обернуть выражение в скобки и добавить 1
    // заменить это:
    $('#api-cat #song'+id+', #api-wb #song'+id+'').index()
    
    // на это:
    ($('#api-cat #song'+id+', #api-wb #song'+id+'').index() + 1)


    Но не стоит городить длинные нечитаемые строки. Как вариант, можно склеивать массив частей через пробел:
    $('h1 em').html([
      'Играет',
      $('#api-cat #song'+id+', #api-wb #song'+id+'').index() + 1,
      'трек из',
      $('h1').attr('data'),
      '<i class="fa fa-cube"><i>',
    ].join(' '));
    Ответ написан
  • Как сделать сплиттест на сайте для кодов JS?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    Просто выводить рандомный вариант текста недостаточно для сплит-теста.
    Надо же дальше собирать статистику, как повели себя сегменты пользователей.
    Сколько из тех, что увидел (какое?) сообщение, зарегистрировался/купил.

    Скрипт у вас из 90-х. Сейчас можно
    как-то так:
    <script>
    {
      const texts = [
        "Фраза 1.",
        "Фраза 2.",
      ];
      const selected = texts[Math.floor(Math.random() * texts.length)];
      const div = document.createElement('div');
      div.innerText = selected;
      document.body.appendChild(div);
    }
    </script>
    Ответ написан
    1 комментарий
  • Как написать числа прописью javascript?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    Готовое: meritt.github.io/rubles
    Ответ написан
    Комментировать
  • Как создать массив из свойств объекта, которые не являются свойствами другого объекта?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    Object.keys(countries).filter(c => !visited.hasOwnProperty(c))

    Массив ключей объекта countries фильтруем,
    оставляя только те, кого нет как свойства в объекте visited
    Ответ написан
    Комментировать
  • Почему промис выдаёт ошибку?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    return забыли:
    return data.response ? Promise.resolve( data.response ) : Promise.reject( data.error );
    Ответ написан
    4 комментария
  • Как заставить этот код работать?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    Для текущего положения «объекта» определить 2 угла, в рамках которых он находится.
    Если хотя бы один из лучей (100 шт) находится внутри диапазона, значит, произошло «касание».

    Предложения.
    1. не рисуйте 100 линий. Проще, наверное, рисовать сектор.
    2. направление луча задавать единственным вектором (единственным углом) и шириной луча в градусах/радианах.
    Ответ написан
  • Почему while (i) – более краткий вариант while (i != 0)?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    Внутри скобок while( ) выражение приводится к одному из двух: true или false. Цикл крутится, пока в скобках всё ещё получается true.

    Например:
    var i = 5;
    
    i != 0            // true, вальсируем дальше
    5                 // любое ненулевое число становится true
    "yes"             // непустая строка тоже true
    {a: "A", b: "B"}  // объекты всегда true
    
    0                 // false
    ""                // пустая строка, false
    undefined         // false
    null              // false
    NaN               // false


    Насчёт чисел ещё раз: только 0 даёт false, остальные числа true.
    Именно поэтому там, где интересует сравнение числа с нулём, удобно-коротко писать прямо число.

    Ещё
    Ещё откройте для себя логические операторы &&, ||, ! их можно использовать не только для проверки двойных условий, но и, например, задавать значение на случай нуля:
    var a = 0;
    
    var b = a || 42; // если a пустое. то в b попадёт запасное значение 42.


    А вот короткий способ привести любое значение к true или false, как внутри скобок while(): дописать перед ним два восклицательных знака!!expressionТут дважды применяется ! – логическое НЕ, которое уже при первом применении сделает из выражения true или false, только зеркально наоборот, и нужен ещё один перевёртыш, чтобы получить задуманное значение.
    Ответ написан
    1 комментарий
  • Передвинуть ползунок на JS?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    У мышиных событий могут проверять атрибут isTrusted, который у настоящих действий пользователя (click, mousemove) true, а при создании таких же событий скриптом — false.
    Ответ написан
    1 комментарий