AngularJS

关注公众号 jb51net

关闭
首页 > 网络编程 > JavaScript > javascript类库 > AngularJS > AngularJS $q 服务

AngularJS中$q 服务的用法详解

作者:无风听海

文章介绍了AngularJS中的$q服务,它是实现Promise机制的核心服务,用于管理和组织异步操作,避免回调地狱,并与AngularJS的Digest机制深度集成,感兴趣的朋友跟随小编一起看看吧

一、$q的定位与设计目的

在 AngularJS 中,$q 是用于实现 Promise(承诺)机制的核心服务,主要用于:

  1. 管理和组织异步操作
  2. 避免回调地狱(callback hell)
  3. 与 AngularJS 的 Digest(脏检查)机制深度集成
  4. $http$timeout$resource 等服务提供统一的异步抽象

$q 的设计思想来源于 Promises/A+ 规范,但在早期 AngularJS 版本中并非完全等同于 ES6 Promise,而是针对 Angular 框架特性进行了扩展。

二、Promise 的核心概念

1. Promise 的三种状态

一个 Promise 对象在生命周期中只可能处于以下三种状态之一:

状态含义
pending初始状态,未完成、未拒绝
fulfilled(resolved)操作成功完成
rejected操作失败

⚠️ 状态一旦从 pending 变为 fulfilledrejected,就不可再改变

2. Promise 的基本行为

三、$q的核心 API

1.$q.defer()—— 延迟对象(Deferred)

(1)基本用法

var deferred = $q.defer();

deferred 对象包含两个关键部分:

属性说明
deferred.promisePromise 对象,对外暴露
deferred.resolve(value)标记成功
deferred.reject(reason)标记失败
deferred.notify(value)进度通知(较少使用)

(2)示例

function asyncTask() {
  var deferred = $q.defer();
  setTimeout(function () {
    if (Math.random() > 0.5) {
      deferred.resolve('成功结果');
    } else {
      deferred.reject('失败原因');
    }
  }, 1000);
  return deferred.promise;
}

调用方:

asyncTask().then(
  function (result) {
    console.log(result);
  },
  function (error) {
    console.error(error);
  }
);

2.promise.then()—— 注册成功与失败回调

(1)语法

promise.then(onFulfilled, onRejected, onNotified);

(2)链式调用(非常重要)

promise
  .then(function (data) {
    return data + 1;
  })
  .then(function (data) {
    return data * 2;
  })
  .then(function (finalResult) {
    console.log(finalResult);
  });

关键原则:

then 的返回值会被自动包装为一个新的 Promise

3.promise.catch()—— 失败处理

(1)语法

promise.catch(function (reason) {
  // 错误处理
});

等价于:

promise.then(null, function (reason) {});

(2)推荐用法

asyncTask()
  .then(processData)
  .then(saveData)
  .catch(handleError);

👉 符合“错误集中处理”的工程实践

4.promise.finally()—— 结束处理

(1)用途

(2)示例

asyncTask()
  .then(successHandler)
  .catch(errorHandler)
  .finally(function () {
    console.log('操作结束');
  });

常用于:

四、$q的静态方法

1.$q.resolve(value)/$q.when(value)

功能

将一个值或 Promise 转换为 $q Promise。

$q.when(10).then(function (value) {
  console.log(value); // 10
});

常用于统一同步 / 异步接口返回值

2.$q.reject(reason)

直接创建一个失败状态的 Promise。

return $q.reject('参数非法');

3.$q.all(promises)

(1)功能

并行执行多个 Promise,全部成功才成功

(2)示例

$q.all({
  user: getUser(),
  order: getOrder()
}).then(function (results) {
  console.log(results.user);
  console.log(results.order);
});

4.$q.race(promises)(较少使用)

五、$q与 AngularJS Digest 机制的关系

这是 $q 区别于原生 Promise核心优势

1. 自动触发$digest

$q.when(data).then(function () {
  $scope.value = 123;
});

2. 对比原生 Promise(早期版本)

Promise.resolve().then(function () {
  $scope.value = 123;
  // 视图可能不会更新
});

六、典型使用场景

1. 封装异步服务

app.service('UserService', function ($q, $http) {
  this.getUser = function (id) {
    var deferred = $q.defer();
    $http.get('/user/' + id)
      .then(function (res) {
        deferred.resolve(res.data);
      })
      .catch(function (err) {
        deferred.reject(err);
      });
    return deferred.promise;
  };
});

2. 串行异步流程控制

login()
  .then(loadProfile)
  .then(loadPermissions)
  .then(initApp)
  .catch(handleError);

七、最佳实践与注意事项

1.优先返回 Promise,而不是 Deferred

❌ 不推荐:

return deferred;

✅ 推荐:

return deferred.promise;

2. 避免“过度使用$q.defer()”

如果已有 Promise,直接返回即可:

return $http.get('/api');

3. 合理使用链式调用,避免嵌套

❌ 回调嵌套
✅ Promise 链

八、总结

$q 是 AngularJS 异步编程的核心机制,其主要特点包括:

到此这篇关于AngularJS中$q 服务的用法的文章就介绍到这了,更多相关AngularJS $q 服务内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

您可能感兴趣的文章:
阅读全文