[Перевод] Коллбэк в JavaScript… Что за зверь?

Комментарии (9)

  • 14 июня 2017 в 15:38 (комментарий был изменён)

    +4

    Коллбэки в JavaScript для дошкольников? Подобные статьи появляются с определённой периодичностью. Но кто-то хоть не просто выдаёт материал 15-летней давности, а про промисы и async пишут. Хотя и по ним уже уйма статей есть.
  • 14 июня 2017 в 15:59 (комментарий был изменён)

    0

    как преобразовать callback:


    function doHomework(subject, callback) {
      alert(`Starting my ${subject} homework.`);
      callback();
      alert('Stop');
    }
    function alertFinished(){
      alert('Finished my homework');
    }
    doHomework('math', alertFinished);

    к промисам:


    function doHomework(subject) {
      return new Promise(function(resolve) {
        alert(`Starting my ${subject} homework.`);
        resolve();
        alert('Stop');
      });
    }
    doHomework('math').then(alert('Finished my homework'));

    ожидаю выполнение alert ('Stop') после alert ('Finished my homework')


    почему работает наоборот?

    • 14 июня 2017 в 16:02

      +1

      Потому что продолжения всегда исполняются асинхронно. Формальное требование для A+/Promises звучит примерно так: «при исполнении продолжения в стеке вызовов не должно быть никаких фреймов кроме инфраструктурных».

      • 14 июня 2017 в 16:22

        0

        вот как можно обойти:


        function doHomework(subject) {
            return new Promise(async function (resolve) {
                alert(`Starting my ${subject} homework.`);
                await resolve();
                alert('Stop');
            });
        }
        doHomework('math').then(alert('Finished my homework'));
        • 14 июня 2017 в 16:29 (комментарий был изменён)

          +2

          В том, что вы написали — нет смысла. resolve(); ничего не возвращает, а применять к нему await бессмысленно. Аналогично бессмысленно делать функцию, переданную в конструктор Promise, асинхронной — никто не будет проверять что она вернула.


          Возможно, вам показалось что все работает как вы задумывали из-за нескольких случайностей. Одна из которых — неправильно созданное продолжение (вы вызываете alert сразу же вместо того чтобы передавать его как замыкание).

    • 14 июня 2017 в 16:07 (комментарий был изменён)

      +1

      Если вам нужно исполнение alert('Stop'); строго после любых прямых продолжений — можно использовать setTimeout:


      function doHomework(subject) {
        return new Promise(resolve => {
          alert(`Starting my ${subject} homework.`);
          resolve();
        })
        .then(() => new Promise(resolve => setTimeout(resolve, 0)))
        .then(() => alert('Stop'));
      }

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

  • 14 июня 2017 в 16:02

    0

    Как-то припозднились. На дворе уже вовсю промисы и уже разворачивается async/await, а вы про коллбеки.

  • 14 июня 2017 в 17:10

    +1

    Ждём статью про циклы и анонимные функции. Блин, серъёзно, что делает этот пост на хабре в 2017?
  • 14 июня 2017 в 17:31

    +1

    весьма распространена калька с оригинального названия: «коллбэк». Если же обойтись без жаргона, то о чём мы говорим, называется «функция обратного вызова».

    Справедливости ради калька — это как раз функция «обратного вызова», а «коллбэк» — лексическое заимствование.

© Habrahabr.ru