Spec-Zone.ru › Angular.js 1.2

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

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

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

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

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

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

// for the purpose of this example let's assume that variables `$q`, `scope` 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 асинхронно вызывает один из обратных вызовов успешного или ошибочного завершения, как только результат станет доступным. Обратные вызовы вызываются с одним аргументом: результатом или причиной отказа. Кроме того, обратный вызов уведомления может быть вызван ноль или более раз для предоставления индикатора прогресса до разрешения или отклонения обещания.

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

  • catch(errorCallback) — сокращенная запись для promise.then(null, errorCallback).

    Поскольку catch является зарезервированным словом в JavaScript, а зарезервированные ключевые слова не поддерживаются в качестве имен свойств ES3, вам необходимо вызвать метод, как promise['catch'](callback) или promise.then(null, errorCallback), чтобы сделать ваш код совместимым с IE8 и Android 2.x.

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

    Поскольку finally является зарезервированным словом в JavaScript, и зарезервированные ключевые слова не поддерживаются в качестве имен свойств ES3, вам необходимо вызвать метод так: promise['finally'](callback), чтобы сделать код совместимым с IE8 и Android 2.x.

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

Поскольку вызов метода 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

Методы

  • 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.2.32/docs/api/ng/service/$q

Spec-Zone.ru

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