Подтвердить что ты не робот

Node.js поток управления: обратные вызовы или promises?

Я знаю, что существует много библиотек потока управления для node.js. Некоторые из них допускают одну цепочку асинхронных функций с обратными вызовами (например, async, asyncblock и т.д.), Другие используют концепцию обещания (Q, отложенные, фьючерсы, и т.д). Учитывая, что длительный script делает ряд действий один за другим, которые могут быть неудачными в любой момент, какой поток управления вы предпочитаете и почему? Каковы плюсы и минусы?

4b9b3361

Ответ 1

Плюсы для обратных вызовов:

  • Простой для понимания и создания.
  • Несколько более эффективный, потому что создано меньше объектов и собран мусор.
  • Node выбрал обратные вызовы (error,result). Я рекомендую следовать их порядку аргумента для согласованности. (В отличие от (result1, result2, result3, error).)

Плюсы для promises:

  • Предоставляет свободный интерфейс, который иногда может помочь уменьшить вложенный аддон обратного вызова, как показанный здесь. Код, по-видимому, протекает линейно путем цепочки вызовов .then(foo).then(bar).
  • Хорошая библиотека promises позволит вам запускать много асинхронных операций в параллельно и продолжать, только когда все они будут завершены. Библиотека Deferred делает это без проблем через map, Q имеет allResolved, а ES6 promises предлагает Promise.all(). (Это также возможно с обратными вызовами, например, используя async.parallel(), но не встроенный.)
  • Хорошая библиотека promises позволит вам указать одну функцию обработки ошибок, которая будет вызываться, если какая-либо из функций очереди выйдет из строя. Для этого с обратными вызовами требуется небольшой шаблон: if (err) return callback(err); в начале каждого обратного вызова.

Было бы разумно использовать обратные вызовы рядом с дном стека, для кода, который будет запускаться много раз в секунду. Выше стека, promises может быть предпочтительнее, так как они легче читать и понимать, и могут обрабатывать ошибки более элегантно.

Стоит отметить, что promises можно построить из callbacks во время выполнения. Таким образом, вы можете реализовать свой основной код в минимальной форме обратного вызова и по-прежнему выставлять версию библиотеки promises, если хотите. (Как в Q.nfbind().)

Мне было бы интересно услышать другие плюсы и минусы.

Бонусный совет: Всегда обрабатывайте ошибки! При использовании обоих методов, если вы не обрабатываете ошибку, она просто исчезнет, ​​в результате чего вы будете в темноте о том, почему ваш код не работал должным образом.

Обратные вызовы должны всегда обрабатывать if (err) ..., а promises всегда должен иметь .catch(), если они не возвращаются.

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

Альтернативой .catch() для promises является прослушивание необработанных отказов. Лично я использую это, чтобы выдать предупреждение о том, что .catch() отсутствует!

Ответ 2

Я не думаю, что есть много объективных плюсов и минусов. Async очень популярен (основанный на npm пакеты, которые зависят от него).

Мне нравятся библиотеки потока управления (в частности async), потому что мне легче понять. Promises запутать меня, в то время как асинхронность понятна. Я подозреваю, что это всего лишь учебная кривая, но Promises будет более читабельным, если я потрачу усилия на их изучение. Но должен ли я ожидать, что люди тоже будут читать мой код?

Существует также 3-й тип - Fibers. Волокна еще не работают в Windows, но (IMO) предлагает самый четкий синтаксис для вещей, которые должны выполняться последовательно.

Ответ 3

Я экспериментировал с декларативным подходом к этой библиотеке: http://chainsjs.org еще больше работать над этим, но это дает вам возможность определять "карту выполнения", где вы можете полностью контролировать поток выполнения из простого сопоставления.