Spec-Zone.ru › Angular.js 1.7

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

  1. $qProvider
  2. Сервис в модуле ng

Обзор

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

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

$q может использоваться двумя способами — один, более похожий на реализацию Q Криса Коваля или Deferred jQuery, и другой, в какой-то степени напоминающий обещания 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 Криса Коваля и $q

Существует два основных отличия:

  • $q интегрирован с механизмом наблюдения модели $rootScope.Scope Scope в AngularJS, что означает более быстрое распространение разрешения или отклонения в ваши модели и избежание ненужных перерисовок браузера, что привело бы к мерцанию пользовательского интерфейса.
  • 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/промисы с привычным поведением 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, [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–2018 Google, Inc.
Licensed under the Creative Commons Attribution License 4.0.
https://code.angularjs.org/1.7.8/docs/api/ng/service/$q

Spec-Zone.ru

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