После того, как Node.js добавил встроенную поддержку обещаний, есть ли еще причины использовать библиотеки, такие как Q или BlueBird?
Например, если вы начинаете новый проект, и давайте предположим, что в этом проекте у вас нет никаких зависимостей, которые используют эти библиотеки, можем ли мы сказать, что на самом деле больше нет причин использовать такие библиотеки?
Ответы:
Старая поговорка гласит, что вы должны выбрать правильный инструмент для работы. ES6 обещает обеспечить основы. Если все, что вы когда-либо хотите или нуждаетесь, - это основы, тогда это должно / могло бы сработать для вас. Но в инструментальном ящике больше инструментов, чем просто основы, и бывают ситуации, когда эти дополнительные инструменты очень полезны. И я бы сказал, что в обещаниях ES6 даже отсутствуют некоторые основы, такие как обещание, которые полезны практически во всех проектах node.js.
Я наиболее знаком с библиотекой обещаний Bluebird, поэтому буду говорить в основном из своего опыта работы с этой библиотекой.
Итак, вот 6 моих главных причин использовать более продвинутую библиотеку Promise
Необещанные асинхронные интерфейсы -
.promisify()
и.promisifyAll()
они невероятно полезны для обработки всех тех асинхронных интерфейсов, которые все еще требуют простых обратных вызовов и еще не возвращают обещания - одна строка кода создает обещанную версию всего интерфейса.Быстрее - Bluebird значительно быстрее, чем обычные обещания в большинстве сред.
Последовательность итераций асинхронного массива -
Promise.mapSeries()
илиPromise.reduce()
позволяет выполнять итерацию по массиву, вызывая асинхронную операцию для каждого элемента, но упорядочивая асинхронные операции так, чтобы они выполнялись одна за другой, а не все одновременно. Вы можете сделать это либо потому, что это требуется целевому серверу, либо потому, что вам нужно передать один результат другому.Polyfill - Если вы хотите использовать обещание в более старых версиях браузеров клиентов, вы будете нуждаться в polyfill в любом случае. С таким же успехом можно получить способный полифилл Так как node.js имеет обещания ES6, вам не нужно многозаполнение в node.js, но вы можете сделать это в браузере. Если вы кодируете как сервер, так и клиент node.js, может быть очень полезно иметь одну и ту же библиотеку обещаний и функции в обоих (проще делиться кодом, переключать контекст между средами, использовать общие методы кодирования для асинхронного кода и т. Д.). .).
Другие полезные функции - Bluebird имеет
Promise.map()
,Promise.some()
,Promise.any()
,Promise.filter()
,Promise.each()
иPromise.props()
все из которых иногда удобно. В то время как эти операции могут быть выполнены с обещаниями ES6 и дополнительным кодом, Bluebird поставляется с этими операциями, уже подготовленными и предварительно протестированными, поэтому их проще и меньше кода использовать.Встроенный в предупреждениях и Full Stack Traces - Bluebird имеет ряд встроенных предупреждений , что предупредить вас о вопросах, которые , вероятно , неправильный код или ошибка. Например, если вы вызываете функцию, которая создает новое обещание внутри
.then()
обработчика, не возвращая это обещание (чтобы связать его с текущей цепочкой обещаний), то в большинстве случаев это случайная ошибка, и Bluebird предупредит вас об этом. эффект. Другие встроенные предупреждения Bluebird описаны здесь .Вот еще несколько подробностей по этим различным темам:
PromisifyAll
В любом проекте node.js я немедленно использую Bluebird везде, потому что я
.promisifyAll()
часто использую в стандартных модулях node.js, таких какfs
модуль.Node.js сам по себе не предоставляет многообещающий интерфейс для встроенных модулей, которые выполняют асинхронный ввод-вывод подобно
fs
модулю. Таким образом, если вы хотите использовать обещания с этими интерфейсами, вам нужно либо вручную написать обертку обещаний вокруг каждой используемой вами функции модуля, либо получить библиотеку, которая может сделать это за вас или не использовать обещания.Bluebird
Promise.promisify()
иPromise.promisifyAll()
обеспечивают автоматическую упаковку асинхронных API-интерфейсов соглашения о вызовах node.js для возврата обещаний. Это чрезвычайно полезно и экономит время. Я использую это все время.Вот пример того, как это работает:
Альтернативой может быть ручное создание собственной оболочки обещаний для каждого
fs
API, который вы хотите использовать:И вы должны вручную сделать это для каждой функции API, которую вы хотите использовать. Это явно не имеет смысла. Это стандартный код. Вы можете также получить утилиту, которая сделает эту работу за вас. Блюберд
Promise.promisify()
иPromise.promisifyAll()
такие утилиты.Другие полезные функции
Вот некоторые из функций Bluebird, которые мне особенно полезны (ниже приведено несколько примеров кода о том, как они могут сохранить код или ускорить разработку):
В дополнение к своей полезной функции,
Promise.map()
также поддерживает параметр параллелизма, который позволяет вам указать, сколько операций должно быть разрешено запускать одновременно, что особенно полезно, когда у вас много дел, но вы не можете перегружать некоторые извне ресурс.Некоторые из них можно назвать автономными и использовать в обещании, которое само по себе разрешается в итерируемое, что может сэкономить много кода.
Polyfill
В проекте браузера, поскольку вы, как правило, хотите поддерживать некоторые браузеры, которые не поддерживают Promise, вам все равно понадобится полифилл. Если вы также используете jQuery, иногда вы можете просто использовать поддержку обещаний, встроенную в jQuery (хотя она до некоторой степени нестандартна, возможно, исправлена в jQuery 3.0), но если проект включает какие-либо существенные асинхронные действия, я нахожу расширенные функции в Bluebird очень полезны.
Быстрее
Также стоит отметить, что обещания Bluebird выглядят значительно быстрее, чем обещания, встроенные в V8. Смотрите этот пост для дальнейшего обсуждения этой темы.
Отсутствует большая вещь Node.js
То, что заставило бы меня задуматься об использовании Bluebird при разработке node.js, было бы, если бы node.js встроил функцию promisify, чтобы вы могли сделать что-то вроде этого:
Или просто предложите уже обещанные методы как часть встроенных модулей.
До этого я делаю это с Bluebird:
Кажется немного странным иметь встроенную поддержку обещаний ES6 в node.js, и ни один из встроенных модулей не возвращает обещания. Это должно быть отсортировано в node.js. До этого я использую Bluebird для обещания целых библиотек. Таким образом, создается впечатление, что обещания реализованы примерно на 20% в node.js, поскольку ни один из встроенных модулей не позволяет использовать обещания с ними без предварительной их переноса вручную.
Примеры
Вот пример простых обещаний против обещания Bluebird и
Promise.map()
для параллельного чтения набора файлов и уведомления о завершении работы со всеми данными:Простые обещания
Синяя птица
Promise.map()
иPromise.promisifyAll()
Вот пример простых обещаний против обещания Bluebird и
Promise.map()
при чтении группы URL-адресов с удаленного хоста, где вы можете читать не более 4 за раз, но хотите поддерживать столько запросов параллельно, сколько это возможно:Простой JS Promises
Обещания Синей птицы
источник
return new Promise(function(resolve, rejct)
. Должно быть:reject
util.promisify
сейчас, хотя прямогоpromisifyAll
эквивалента нет.fs
, но все же есть некоторые другие причины использовать Bluebird (мой любимыйconcurrency
вариант - вариантPromise.map()
), чтобы не перегружать целевой сервис, к которому вам нужно сделать кучу параллельных запросов. Кроме того, все еще много других не обещанных интерфейсов, чтобы использовать promisifyAll от Bluebird. Но постепенно причины немедленного использования Bluebird в каждом новом проекте исчезают, так как сам node.js усиливает встроенную поддержку обещаний.