Асинхронне програмування JavaScript. Використання Deferred та Promise. - Блог ITVDN
ITVDN: курси програмування
Відеокурси з
програмування

    Обери свою IT спеціальність

    Підписка

    Обери свою IT спеціальність

    Підписка

      Асинхронне програмування JavaScript. Використання Deferred та Promise.

      advertisement advertisement

      Введение

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


      Асинхронное программирование в JavaScript

      Асинхронное программирование в JavaScript не связано с многопоточностью. JavaScript – однопоточный, это означает, что не существует стандартных языковых конструкций, которые позволят создать в приложении дополнительный поток для выполнения параллельных вычислений (единственная возможность организовать настоящую многопоточность – использовать Web Workers). Асинхронное программирование – стиль программирования, при котором результат работы функций доступен не сразу, а через некоторое время. Асинхронная функция – это функция, после вызова которой JavaScript приложение продолжает работать, потому что функция сразу выполняет возврат. Результат работы асинхронной функции становится известным позже, и для того, чтобы оповестить наше приложении о полученных значениях, асинхронная функция вызывает другую функцию (callback), которую мы передаем в аргументах при запуске.

      Например, getDataFromServer(onSuccess); getDataFromServer – асинхронная функция, выполняющая запрос на сервер, onSuccess – callback функция или функция обратного вызова, которая запускается при успешном завершении операции обращения к серверу.

      Использование callback функций может привести к появлению проблемы, которую называют Pyramid of Doom – callback функция, в которой вызывается асинхронная функция, которой передается callback функция, и в ней же вызывается асинхронная функция и т.д.

      step1(function(result1) {

             step2(function(result2) {

                   step3(function(result3) {

                          // и т.д.

                   });

             });

      });

      Такой код тяжело читать и сопровождать. Для того, чтобы подобных проблем не было , мы можем использовать различные шаблоны для организации кода. Один из таких шаблонов - Promise. (Другие варианты организации асинхронного кода можно посмотреть в этой статье)

      Что такое Promise (ECMAScript 6)

      Promise – прокси объект, который представляет еще не известное значение (значение будет доступно после завершения асинхронной операции). С Promise можно ассоциировать две функции: первая - для выполнения операции, если асинхронная задача завершилась успешно. И вторая - для операции в случае ошибки.

      Promise может находиться в одном из трех состояний:

      • pending;
      • fulfilled;
      • rejected.

      Например, мы выполняем AJAX запрос с помощью асинхронной функции, которая возвращает Promise. Как только мы выполним запрос, функция создаст Promise, который будет в состоянии pending. Когда сервер вернет ответ, Promise перейдет в состояние fulfilled, если ответ был 200 OK, или в состояние rejected, если статус код был 500 Internal Server Error (или другой код ошибки). При переходе в fullfiled состояние Promise будет содержать ответ от сервера, при переходе в rejected – ошибку или текст ошибки (все зависит от реализации асинхронной функции).

      Как только Promise меняет свое состояние, запускается функция, которая была зарегистрирована как реакция на соответствующее состояние.

      Пример использования асинхронной функции download, которая возвращает Promise:

      download("data.txt").then(function (data) {

          console.log(data);

      }, function (error) {

          console.error(error);

      });

      или такая запись

      var p = download("data.txt");

      p.then(onFulfilled, onRejected);

      function onFulfilled(data) {

          console.log(data);

      }

      function onRejected(error) {

          console.error(error);

      }

      Для того, чтобы установить, что произойдет после завершения асинхронной операции, на объекте Promise необходимо вызвать метод then. Этот метод принимает два аргумента:

      1. обработчик для состояния fulfilled
      2. обработчик для состояния rejected

      Функцию then можно вызвать в любой момент, даже если асинхронная операция уже завершена и Promise перешел из состояния pending. Если вызвать then на Promise, который уже находится в конкретном состоянии, то будет вызвана соответствующая состоянию функция, переданная в метод then.

      Ниже приведен код асинхронной функции download.

      function download(url) {

          // Создание нового объекта Promise

          return new Promise(function (resolve, reject) {

              var req = new XMLHttpRequest();

              req.open('GET', url);

              req.onload = function () {

                  if (req.status == 200) {

                      // перевод Promise в состояние fulfilled.

                      // req.response - данные доступные в функции-обработчике

                      // перехода состояния

                      resolve(req.response);

                  }

                  else {

                      // перевод Promise в состояние rejected

                      reject(Error(req.statusText));

                  }

              };

              // Обработка сетевых ошибок

              req.onerror = function () {

                  // перевод Promise в состояние rejected

                  reject(Error("Network Error"));

              };

              // отправка запроса на сервер

              req.send();

          });

      }

      Поддержка Promise браузерами http://caniuse.com/#search=Promise

      Библиотеки для работы с Promise

      Есть много различных библиотек, которые реализуют спецификацию объекта Promise. Поэтому проблему слабой поддержки Promise ECMAScript 6 можно решить, применив одну из следующих библиотек:

      jQuery http://jquery.com/

      Q https://github.com/kriskowal/q

      When https://github.com/cujojs/when

      WinJs http://msdn.microsoft.com/en-us/library/windows/apps/br211867.aspx

      RSVP.js https://github.com/tildeio/rsvp.js

      КОМЕНТАРІ ТА ОБГОВОРЕННЯ
      advertisement advertisement

      Купуй передплатуз доступом до всіх курсів та сервісів

      Бібліотека сучасних IT знань у зручному форматі

      Вибирай свій варіант підписки залежно від завдань, що стоять перед тобою. Але якщо потрібно пройти повне навчання з нуля до рівня фахівця, краще вибирати Базовий або Преміум. А для того, щоб вивчити 2-3 нові технології, або повторити знання, готуючись до співбесіди, підійде Пакет Стартовий.

      Стартовий
      • Усі відеокурси на 3 місяці
      • Тестування з 10 курсів
      • Перевірка 5 домашніх завдань
      • Консультація з тренером 30 хв
      59.99 $
      Придбати
      Базовий
      • Усі відеокурси на 6 місяців
      • Тестування з 16 курсів
      • Перевірка 10 домашніх завдань
      • Консультація з тренером 60 хв
      89.99 $
      Придбати
      Преміум
      • Усі відеокурси на 1 рік
      • Тестування з 24 курсів
      • Перевірка 20 домашніх завдань
      • Консультація з тренером 120 хв
      169.99 $
      Придбати
      Notification success
      Ми використовуємо cookie-файли, щоб зробити взаємодію з нашими веб-сайтами та послугами простою та значущою.