Promise. Работаем с асинхронным JavaScript

June 30, 2015

Многие разработчики сталкиваются с проблемой асинхронности в JS, особенно когда из-за неё код превращается кучу колбеков. Даже обычное чтение из базы данных превращается в ужас, потому что весь код обработки данных приходится писать в колбеке.

Приступим к разбору

Условимся, что функция readDataFromDB нативная и работает асинхронно.

Так выглядит вызов нашей асинхронной функции:

readDataFromDB(function(err, data) {
if(err) {
//error handle
}
//other code
});

Как видно, с отловом ошибок также проблема, так как его реализация пишется прямо в колбеке, что не очень удобно. Почему? Ответ прост: потому что на обработку этой ошибки могут претендовать разные части вашего приложения, как в общем-то и на обработку удачного выполнения чтения.

Уверен, что от увиденного уже хочется бежать, но есть выход из ситуации! Сразу скажу, что этот выход не решение всех проблем, но он может помочь вам сделать код более понятным и сделать работу с асинхронностью более удобной. С этим нам помогут Promise (промисы || обещания).

Немого о том, как работаю промисы. Промис — обертка над асинхронностью, и логика её такова, что впоследствии получаем два случая: resolve — случай, когда всё прошло успешно и reject — случай, когда всё прошло менее успешно, т.е. неудачно.

Конструктор промиса выглядит следующим образом:

Promise(executor);

executor — функция, в которую будет заключена асинхронность. Функция-экзекутор на вход принимает два аргумента, те самые resolve и code>reject. Аргументы resolve и reject являются функциями, которые должны будут быть вызваны, в зависимости от ситуации.

new Promise(function(resolve, reject) {
//do smth
});

Давайте обернём нашу асинхронную функцию readDataFromDBв промис:

//создаем промис
var p = new Promise(function(resolve, reject) {
//вызываем функцию
readDataFromDB(function(err, data) {
if(!err) {
resolve(data);
} else {
reject(err);
}
});
});

Теперь в случае ошибки, вызовется reject, а в случае удачи вызовется resolve, в которую передадутся данные.

Что мы получили на данный момент? У нас есть отдельная часть логики, которая может дать нам два варианта ответа, ориентируясь на которые мы будем принимать решения о дальнейших действиях.

Двигаемся дальше. Теперь надо определить обработчики. Для этого существует два метода — then и catch. Оба на вход принимают функцию, в которую будут сообщены данные. Метод then выполнится в случае, если будет вызван resolve, соответственно catch, если будет вызван reject.

p.then(function(data) {
console.log('resolved');
});

p.catch(function(err) {
console.log('rejected');
});

Стоит сказать, что метод then может принимать на вход обработчик для resolve и reject.

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

На данный момент, ещё не все браузеры нативно поддерживают эту технологию, но её реализации можно встретить в jQuery, AngularJS, basis.js и это не весь список.

Запись Promise. Работаем с асинхронным JavaScript впервые появилась For Web.


Source: http://forwebdev.ru

Комментарии

comments powered by Disqus