@zuart
Программист, администратор, архитектор...

Callback / Promises / await — что быстрее и экономичнее?

Приветствую.

С ES6 появились промисы, в ES7 добавлены async/await - всюду публикуют рекомендации отказываться от callback-ов т.к. это понятнее и синтаксически "правильнее", но в то же время противоречивые данные по принципам работы (в целом пишут, что промисы и асинк/авайт - это "сахар").

В текущем проекте так складывается, что синтаксически вложенности более 2-х уровней колбеков нет и не будет, однако есть несколько модулей, требования к которым по скорости работы и затратам памяти очень "жестокие". И в первую очередь это связано с "замыканиями" и соответственно динамическим выделением памяти/ее очисткой + создание/удаление самих функций-обработчиков. Объекты местами довольно "тяжелые" и очень хочется максимально избежать лишних операций.

Соответственно вопрос - что же все-таки использовать правильнее в таких условиях (ведь если промисы и асинк/авайт только "сахар", то помимо накладных расходов от колбеков добавляется еще и эта "сахароза")? И почему?

И да, к слову, ситуация складывается так, что все это добро оформлено в классы и присутствует "условие" непредсказуемого количества повторений, что-то вроде (в синтаксисе async / await - так реально максимально понятно просто, если текущий вариант на колбеках постить, будет длинный и непростой код):

class a {
  async updateMovies() {
    let v = ....;
    while (await a(v)) {
      ... тут повторяемый код метода
      ... некие операции с "v"
    };
    ... тут код завершения метода
  };

  async a(v) {
    ...
  };
};
  • Вопрос задан
  • 1494 просмотра
Решения вопроса 1
crazy_leo
@crazy_leo
Frontend Developer
Если для вас производительность так критична, пишите на базе, т.е на колбэках.
Если для вас встроенный метод массива, для фильтрации элементов критичен по производительности, пишите алгоритм.

Колбэк сработает быстрее, чем промис, это очевидно. И еще промис является микрозадачей и является в любом случае ассинхронным, чего не скажешь о колбэк.
Ответ написан
Пригласить эксперта
Ответы на вопрос 5
sergey-gornostaev
@sergey-gornostaev
Седой и строгий
Соответственно вопрос - что же все-таки использовать правильнее

То, что делает код чище, понятнее и проще для сопровождения. А это async/await при прочих равных.

если промисы и асинк/авайт только "сахар", то помимо накладных расходов от колбеков добавляется еще и эта "сахароза

Не добавится. Весь сахар растворится при парсинге скрипта, в AST его уже не будет.
Ответ написан
Xuxicheta
@Xuxicheta
инженер
Да, есть небольшой оверхэд от промисов, но выгоднее писать понятный код и купить плюс одну виртуалку, чем экономить на спичках и утонуть в аде коллбэков

1*I5Zr32SJK0Aic3Ru7EU1KQ.png

Если у вас там ничего сложного, используйте коллбеки, в разумном масштабе ничего страшного. Но обычно, если требования к скорости суровы, берут не js, а компилируемый язык модный типа golang или модуль на C/C++ пишут.
Ответ написан
@sh84
async синтаксис безусловно выигрывает по читабельности и простоте.
Будет ли значимый выигрыш при использование callback-ов - можно выяснить только с помощью тестов производительности и/или профилирования.
По моему опыту с 90% вероятностью окажется что разницы нет.
Ответ написан
MDiMaI666
@MDiMaI666
Талантливый программист
по идее разница все равно не велика должна быть. попробуйте так и так написать участок и запустите тесты произволительности, будет однозначно ясно.
Ответ написан
profesor08
@profesor08
Твой код все равно будет трансплититься в понятный большинству браузеров. И независимо от того, как ты напишешь свой код, затык по производительности не исправится сам по себе. Тебе надо его выявить, а потом думать как исправить. Более чисты код тебе поможет. Вот у тебя есть вложенные асинхронные вызовы, если следующий не зависит от данных предыдущего, то их можно вызывать по отдельности, не дожидаясь пока завершится один, а уже где-то ниже по коду обрабатывать их результаты. Вот подобное делать с промисами самое то, async/await избавит от написания колбеков.

// долго, так как сначала ждем а, потом б
// если на выполнение каждого надо по 5 сек, итоговое время выполнения будет 10 сек
async function sum(a, b) {
  const a = await getA();
  const b = await getB();

  return a + b;
}

// быстро, так как создали по промису, и они одновременно обрабатываются, потом только ждем их результатов.
// если на выполнение каждого надо по 5 сек, итоговое время выполнения будет 5 сек
async function sum(a, b) {
  const a = getA();
  const b = getB();

  return await a + await b;
}
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы