使用 q 服务的 Angular 承诺

$q 是一个内置服务,它有助于执行异步函数并在完成处理时使用它们的返回值(或异常)。

$q$rootScope.Scope 模型观察机制集成,这意味着更快地将分辨率或拒绝传播到模型中,避免不必要的浏览器重绘,这将导致 UI 闪烁。

在我们的例子中,我们调用我们的工厂 getMyData,它返回一个 promise 对象。如果对象是 resolved,则返回一个随机数。如果是 rejected,它会在 2 秒后返回拒绝并显示错误消息。

在 Angular 工厂

function getMyData($timeout, $q) {
  return function() {
    // simulated async function
    var promise = $timeout(function() {
      if(Math.round(Math.random())) {
        return 'data received!'
      } else {
        return $q.reject('oh no an error! try again')
      }
    }, 2000);
    return promise;
  }
}

在调用中使用 Promise

angular.module('app', [])
.factory('getMyData', getMyData)
.run(function(getData) {
  var promise = getData()
    .then(function(string) {
      console.log(string)
    }, function(error) {
      console.error(error)
    })
    .finally(function() {
      console.log('Finished at:', new Date())
    })
})

要使用 promises,请将 $q 注入依赖项。我们在 getMyData 工厂注入了 $q

var defer = $q.defer();

通过调用 $q.defer() 构造一个新的 deferred 实例

延迟对象只是一个公开 promise 的对象,以及解析该 promise 的相关方法。它使用 $q.deferred() 函数构建,并暴露出三种主要方法:resolve()reject()notify()

  • resolve(value) - 使用值解析派生的 promise。
  • reject(reason) - 拒绝派生的承诺。
  • notify(value) - 提供有关承诺执行状态的更新。在承诺被解决或拒绝之前,可以多次调用此方法。

属性

通过 promise 属性访问关联的 promise 对象。promise - {Promise} - 与此延迟相关联的 promise 对象。

创建延迟实例时会创建一个新的 promise 实例,并可以通过调用 deferred.promise 来检索。

promise 对象的目的是允许感兴趣的各方在完成时访问延迟任务的结果。

承诺方法 -

  • then(successCallback, [errorCallback], [notifyCallback]) - 无论何时或将要解决或拒绝承诺,只要结果可用,就会异步调用其中一个成功或错误回调。使用单个参数调用回调:结果或拒绝原因。另外,在解决或拒绝承诺之前,可以将通知回调调用零次或多次以提供进度指示。

  • catch(errorCallback) - promise.then 的简写(null, errorCallback)

  • finally(callback, notifyCallback) - 允许你观察承诺的履行或拒绝,但是在不修改最终值的情况下这样做。

承诺最强大的功能之一是将它们链接在一起的能力。这允许数据流过链并在每一步被操作和变异。以下示例演示了这一点:

例 1:

// Creates a promise that when resolved, returns 4.
function getNumbers() {

  var promise = $timeout(function() {
    return 4;
  }, 1000);
  
  return promise;
}

// Resolve getNumbers() and chain subsequent then() calls to decrement
// initial number from 4 to 0 and then output a string.
getNumbers()
  .then(function(num) {
      // 4
      console.log(num);
      return --num;
  })
  .then(function (num) {
      // 3
      console.log(num);
      return --num;
  })
   .then(function (num) {
      // 2
      console.log(num);
      return --num;
  })
  .then(function (num) {
      // 1
      console.log(num);
      return --num;
  })
  .then(function (num) {
      // 0
      console.log(num);
      return 'And we are done!';
  })
  .then(function (text) {
      // "And we are done!"
      console.log(text);        
  });