Spec-Zone.ru › Angular.js 1.5

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

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

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

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

$q может использоваться двумя способами: одним, более похожим на реализацию Kris Kowal's Q или jQuery's Deferred, и другим, в некоторой степени напоминающим обещания ES6 (ES2015).

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

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

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

Его можно использовать так:

// 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.

Примечание: в отличие от поведения 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. Аргументы errorCallback и 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 от Kris Kowal и $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

    Возвращает новый экземпляр deferred.

  • reject(reason);

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

    При сравнении deferred/promised с привычным поведением try/catch/throw, think of 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, [successCallback], [errorCallback], [progressCallback]);

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

    Параметры

    Параметр Тип Подробности
    value *

    Значение или промис

    successCallback
    (необязательно)
    Function=
    errorCallback
    (необязательно)
    Function=
    progressCallback
    (необязательно)
    Function=

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

    Promise

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

  • resolve(value, [successCallback], [errorCallback], [progressCallback]);

    Псевдоним для when для сохранения согласованности именования с ES6.

    Параметры

    Параметр Тип Подробности
    value *

    Значение или промис

    successCallback
    (необязательно)
    Function=
    errorCallback
    (необязательно)
    Function=
    progressCallback
    (необязательно)
    Function=

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

    Promise

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

  • all(promises);

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

    Параметры

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

    Массив или хеш промисов.

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

    Promise

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

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

Spec-Zone.ru

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