Spec-Zone.ru › Angular.js 1.3

Улучшить эту документацию Просмотреть исходный код $q

  1. сервис в модуле ng

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

Это реализация объектов обещаний/отложенных объектов, вдохновлённая Q от Криса Коваля.

$q может быть использован двумя способами: один более похож на Q от Криса Коваля или реализацию Deferred в jQuery, а другой в некоторой степени напоминает обещания ES6.

$q конструктор

Упрощённое обещание в стиле ES6 в основном использует $q как конструктор, который принимает resolver функцию в качестве первого аргумента. Это аналогично реализации Promise из ES6 Harmony, см. MDN.

Хотя использование в стиле конструктора поддерживается, не все вспомогательные методы из обещаний ES6 Harmony доступны пока.

Он может быть использован так:

// for the purpose of this example let's assume that variables `$q` and `okToGreet`
// are available in the current lexical scope (they could have been injected or passed in).

function asyncGreet(name) {
  // perform some asynchronous operation, resolve or reject the promise when appropriate.
  return $q(function(resolve, reject) {
    setTimeout(function() {
      if (okToGreet(name)) {
        resolve('Hello, ' + name + '!');
      } else {
        reject('Greeting ' + name + ' is not allowed.');
      }
    }, 1000);
  });
}

var promise = asyncGreet('Robin Hood');
promise.then(function(greeting) {
  alert('Success: ' + greeting);
}, function(reason) {
  alert('Failed: ' + reason);
});

Примечание: колбэки progress/notify в настоящее время не поддерживаются через интерфейс в стиле ES6.

Однако более традиционное использование в стиле CommonJS по-прежнему доступно и документировано ниже.

Предложение CommonJS для обещаний описывает обещание как интерфейс для взаимодействия с объектом, представляющим результат асинхронного действия, которое может быть завершено или нет в любой момент времени.

С точки зрения обработки ошибок, API отложенных задач и обещаний относятся к асинхронному программированию так же, как try, catch и throw ключевые слова относятся к синхронному программированию.

// for the purpose of this example let's assume that variables `$q` and `okToGreet`
// are available in the current lexical scope (they could have been injected or passed in).

function asyncGreet(name) {
  var deferred = $q.defer();

  setTimeout(function() {
    deferred.notify('About to greet ' + name + '.');

    if (okToGreet(name)) {
      deferred.resolve('Hello, ' + name + '!');
    } else {
      deferred.reject('Greeting ' + name + ' is not allowed.');
    }
  }, 1000);

  return deferred.promise;
}

var promise = asyncGreet('Robin Hood');
promise.then(function(greeting) {
  alert('Success: ' + greeting);
}, function(reason) {
  alert('Failed: ' + reason);
}, function(update) {
  alert('Got notification: ' + update);
});

Поначалу может не быть очевидно, почему эта дополнительная сложность стоит усилий. Выгода заключается в гарантиях, которые обеспечивают API обещаний и отложенных задач, см. https://github.com/kriskowal/uncommonjs/blob/master/promises/specification.md.

Кроме того, API обещаний позволяет для композиции, что очень сложно сделать с традиционным подходом с передачей колбэков (CPS). Более подробную информацию об этом см. в документации Q, особенно раздел о последовательном или параллельном объединении обещаний.

API отложенных задач

Новый экземпляр отложенной задачи создаётся путем вызова $q.defer().

Цель объекта отложенной задачи — предоставить связанный объект обещания, а также API, которые могут быть использованы для сигнализации об успешном или неудачном завершении, а также о состоянии задачи.

Методы

  • resolve(value) — разрешает производное обещание со значением value. Если значение представляет собой отказ, созданный с помощью $q.reject, обещание будет отклонено вместо этого.
  • reject(reason) — отклоняет производное обещание со значением reason. Это эквивалентно разрешению с помощью отклонения, созданного с помощью $q.reject.
  • notify(value) — предоставляет обновления о состоянии выполнения обещания. Это может быть вызвано несколько раз до тех пор, пока обещание не будет разрешено или отклонено.

Свойства

  • promise — {Promise} — объект обещания, связанный с этой отложенной задачей.

API обещаний

Новый экземпляр обещания создаётся при создании экземпляра отложенной задачи и может быть получен путем вызова deferred.promise.

Цель объекта обещания — предоставить заинтересованным сторонам доступ к результату задачи, когда она завершится.

Методы

  • then(successCallback, errorCallback, notifyCallback) — независимо от того, когда обещание было или будет разрешено или отклонено, then асинхронно вызывает один из колбэков успеха или ошибки, как только результат станет доступен. Колбэки вызываются с одним аргументом: результатом или причиной отклонения. Кроме того, колбэк notify может быть вызван ноль или более раз для предоставления показателя прогресса до того, как обещание будет разрешено или отклонено.

    Этот метод возвращает новое обещание, которое разрешается или отклоняется через возвращаемое значение successCallback, errorCallback. Он также отправляет уведомления через возвращаемое значение метода notifyCallback. Обещание не может быть разрешено или отклонено из метода notifyCallback.

  • catch(errorCallback) — сокращённая форма promise.then(null, errorCallback)

  • finally(callback, notifyCallback) — позволяет наблюдать за выполнением или отклонением обещания, но не изменяя конечное значение. Это полезно для освобождения ресурсов или выполнения какой-либо очистки, которая должна быть выполнена, независимо от того, было ли обещание отклонено или выполнено. Более подробную информацию см. в полном спецификации.

Цепочки обещаний

Поскольку вызов метода then обещания возвращает новое производное обещание, легко создать цепочку обещаний:

promiseB = promiseA.then(function(result) {
  return result + 1;
});

// promiseB will be resolved immediately after promiseA is resolved and its value
// will be the result of promiseA incremented by 1

Можно создавать цепочки любой длины, и так как обещание может быть разрешено другим обещанием (что отложит его разрешение дальше), можно приостановить/отложить разрешение обещаний в любой точке цепочки. Это позволяет реализовывать мощные API, такие как обработчики ответов $http.

Отличия между Q от Криса Коваля и $q

Есть два основных отличия:

  • $q интегрирован с механизмом наблюдения $rootScope.Scope Scope модели в Angular, что означает более быстрое распространение разрешения или отклонения в ваши модели и избежание ненужных перерисовок браузера, что приведет к мерцанию пользовательского интерфейса.
  • Q имеет гораздо больше функций, чем $q, но это влечет за собой затраты на объём данных. $q крошечный, но содержит всю необходимую функциональность для общих асинхронных задач.

    Тестирование

    it('should simulate promise', inject(function($q, $rootScope) {
      var deferred = $q.defer();
      var promise = deferred.promise;
      var resolvedValue;
    
      promise.then(function(value) { resolvedValue = value; });
      expect(resolvedValue).toBeUndefined();
    
      // Simulate resolving of promise
      deferred.resolve(123);
      // Note that the 'then' function does not get called synchronously.
      // This is because we want the promise API to always be async, whether or not
      // it got called synchronously or asynchronously.
      expect(resolvedValue).toBeUndefined();
    
      // Propagate promise resolution to 'then' functions using $apply().
      $rootScope.$apply();
      expect(resolvedValue).toEqual(123);
    }));
    

Зависимости

  • $rootScope

Использование

$q(resolver);

Аргументы

Параметр Тип Описание
resolver function(function, function)

Функция, ответственная за разрешение или отклонение вновь созданного обещания. Первый параметр — функция, разрешающая обещание, второй — функция, отклоняющая обещание.

Возвращаемое значение

Promise

Новое созданное обещание.

Методы

  • defer();

    Создаёт объект Deferred , который представляет задачу, которая завершится в будущем.

    Возвращаемое значение

    Deferred

    Возвращает новый экземпляр отложенной задачи.

  • reject(reason);

    Создаёт обещание, которое разрешается как отклоненное со значением reason . Этот API следует использовать для передачи отклонения в цепочке обещаний. Если вы работаете с последним обещанием в цепочке обещаний, вам об этом не нужно беспокоиться.

    Сравнивая отложенные задачи/обещания с привычным поведением try/catch/throw, подумайте об reject как об ключевом слове throw в JavaScript. Это также означает, что если вы «перехватываете» ошибку через обратный вызов ошибки обещания и хотите переслать ошибку в производное обещание от текущего обещания, вы должны «перебросить» ошибку, вернув отклонение, созданное с помощью reject.

    promiseB = promiseA.then(function(result) {
      // success: do something and resolve promiseB
      //          with the old or a new result
      return result;
    }, function(reason) {
      // error: handle the error if possible and
      //        resolve promiseB with newPromiseOrValue,
      //        otherwise forward the rejection to promiseB
      if (canHandle(reason)) {
       // handle the error and recover
       return newPromiseOrValue;
      }
      return $q.reject(reason);
    });
    

    Параметры

    Параметр Тип Описание
    reason *

    Константа, сообщение, исключение или объект, представляющий причину отклонения.

    Возвращаемое значение

    Promise

    Возвращает обещание, которое уже было разрешено как отклоненное со значением reason.

  • when(value);

    Оборачивает объект, который может быть значением или (третьим лицом) обещанием, в обещание $q. Это полезно, когда вы работаете с объектом, который может быть или не быть обещанием, или если обещание поступает от источника, которому нельзя доверять.

    Параметры

    Параметр Тип Описание
    value *

    Значение или обещание

    Возвращаемое значение

    Promise

    Возвращает обещание переданного значения или обещания

  • all(promises);

    Объединяет несколько обещаний в одно обещание, которое разрешается, когда все входные обещания разрешены.

    Параметры

    Параметр Тип Описание
    promises Array.<Promise>Object.<Promise>

    Массив или хеш обещаний.

    Возвращаемое значение

    Promise

    Возвращает единственное обещание, которое будет разрешено массивом/хешем значений, каждое значение соответствует обещанию в том же индексе/ключе в promises массиве/хеше. Если любое из обещаний разрешено с отказом, это итоговое обещание будет отклонено с тем же значением отказа.

© 2010–2017 Google, Inc.
Licensed under the Creative Commons Attribution License 4.0.
https://code.angularjs.org/1.3.20/docs/api/ng/service/$q

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API