Теперь, когда Promises/A+ находят свой путь на все больше и больше платформ (но не без проблем), пришло время воспользоваться этим прекрасным способом работы с асинхронными операциями. Промисы могут показаться простыми, если вы знакомы с библиотеками асинхронных потоков управления, но могут быть пугающими, если вы привыкли только к вложенным обратным вызовам.

Основное обещание

Обещание — это объект, который либо выполняется, либо отклоняется в будущем или, возможно, сразу. Обещает либо вызвать функцию resolve при успешном завершении, либо вызвать функцию reject при возникновении ошибки (в отличие от шаблона обратного вызова error-first). Пока не будет вызвана ни одна из функций, мы считаем обещание ожидающим выполнения.

Работа с обещаниями состоит из двух шагов. Сначала вы определяете обещание и указываете действия, которые оно должно выполнять. Это включает в себя, когда вызывать функции resolve или reject. Как только вы определили обещание, вы можете вызвать его, вызвав then для объекта обещания.

Передавая два обратных вызова функции then, вы указываете, что должно делать промис, когда он разрешается или отклоняется. Аргумент, который передается этим функциям, — это значение, которое вы передали функции resolve или reject в определении промиса. В приведенном ниже примере это либо литерал объекта {status: ‘ok’}, либо строка ‘Ой, что-то пошло не так’.

(В примерах я использую библиотеку обещаний, включенную в Ember.js, но подойдет любая библиотека, соответствующая спецификации.)

Обещания в сериале

Все становится интереснее, когда нам приходится иметь дело с несколькими обещаниями. В цепочке обещаний мы можем вернуть обещание из функции then .

Этот пример показывает преимущества использования промисов; асинхронный код становится намного легче читать, а справляться с ошибками становится совсем легко! Функция catch просто вызывается, когда одно из связанных обещаний отклоняется.

Обещания параллельно

Когда вы можете выполнять операции параллельно, вы можете использовать некоторые базовые конструкции, чтобы сделать ваш асинхронный код еще более удобным для чтения. Вы также можете смешивать и сочетать последовательные и параллельные операции. Ранее на этой неделе я работал над приложением, в котором мне приходилось разрешать несколько ключевых слов через RESTful API перед сохранением модели.

Действие submitForm объединяет два обещания. Первый promises пытается разрешить ключевые слова; второй сохраняет модель. В функции resolveKeywords определяется новое обещание, которое вызывает обещание (resolveSingleKeyword) для каждого ключевого слова и назначает его обещаниям. Используя функцию RSVP all, мы ждем разрешения всех обещаний и только затем разрешаем обещание resolveKeywords.

Вывод

Обещания — это универсальная конструкция, упрощающая чтение и анализ вашего асинхронного кода. Такие фреймворки, как Ember.js, повсеместно используют промисы, и нет никаких причин не использовать промисы в коде вашего приложения. Поначалу их может быть трудно понять, но научиться эффективно использовать промисы может реально сэкономить время.