AngularJS调接口异步变同步处理

1.背景

在前端项目中,经常会遇到页面有多个接口,后一个接口参数需要从前一个接口的返回数据中获取,这就存在接口必须按顺序一个一个执行。而Angular提供的Http服务请求接口都是异步请求,因此通常情况下会写成如下的代码:

funA(arg1,arg2,function(){
    funcB(arg1,arg2,function(){
        funcC(arg1,arg2,function(){
             xxxx....
        })
    })   
});

这种方式会造成页面代码混乱不易维护
应用场景:如果有一个需求需要先获取用户信息(如getUser()),之后获取用户权限(如getPermission())。假设两个方法都是异步的,那在直接调用的时候:

getUser();
getPermission();

这样有可能出现在得到用户信息前就调用getPermission()方法,这样逻辑就有问题就会出错。

2.Promise

针对这种现象,Angular推出了Promise规范,它可以帮助开发者将异步变成同步,避免了层层嵌套的回调函数。Promise 就像一个中介,它承诺会将一个可信任的异步结果返回。首先 Promise 和异步接口签订一个协议,成功时,调用resolve函数通知Promise,异常时,调用reject通知 Promise。

3.$q服务

在angularjs中创建promise,可以使用内置的q服务,q服务是AngularJs中自己封装实现的一种Promise实现,一般有如下三个常用方法:
defer() :创建一个deferred对象,这个对象可以执行几个常用的方法,比如resolve,reject,notify等;
all() :传入Promise的数组,批量执行,返回一个Promise对象;
when() :传入一个不确定的参数,如果符合Promise标准,就返回一个Promise对象。

3.1 defer()方法

在$q服务中,用defer()方法创建一个deferred对象。

var defer = $q.defer();

然后这个对象可以调用resolve方法定义成功状态,使用reject方法定义失败状态,并且可以在这些方法中传递参数,一般接口返回的数据都是用这些方法传递出去。
最后通过deferred对象 .promise来返回一个promise对象。

return defer.promise;

3.2 链式调用

一般处理多个接口需要嵌套执行时,可采用angular的链式调用,即:
FunA.then().then().then();
在then方法中return 要调用的下一个接口。如下funA、funB、funC都是返回了promise对象的方法,如果执行顺序为funA、funB、funC,则可用链式调用。

function funA(num){
  var defer = $q.defer();
  if(num<5){
    defer.resolve('funA success');
  }else{
    defer.reject('funA error');
  }
  return defer.promise; 
}
 
function funB(num){
  var defer = $q.defer();
  if(num<5){
    defer.resolve('funB success');
  }else{
    defer.reject('funB error');
  }
  return defer.promise;
}
 
function funC(num){
  var defer = $q.defer();
  if(num<5){
    defer.resolve('funC success');
  }else{
    defer.reject('funC error');
  }
  return defer.promise;
}

方法调用:
funA(3).then(function(success){
  console.log(success);
  return funB(3);
}).then(function(success){
  console.log(success);
  return funC(3);
});

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 前言 本文旨在简单讲解一下javascript中的Promise对象的概念,特性与简单的使用方法。并在文末会附上一...
    _暮雨清秋_阅读 6,618评论 0 3
  • JavaScript里通常不建议阻塞主程序,尤其是一些代价比较昂贵的操作,如查找数据库,下载文件等操作,应该用异步...
    张歆琳阅读 7,650评论 0 12
  • 抽象来说,deferreds 可以理解为表示需要长时间才能完成的耗时操作的一种方式,相比于阻塞式函数它们是异步的,...
    北方蜘蛛阅读 5,442评论 1 5
  • Promise 的含义 一句话概括一下promise的作用:可以将异步操作以同步操作的流程表达出来,避免了层层嵌套...
    雪萌萌萌阅读 10,868评论 0 7
  • 原文地址:http://es6.ruanyifeng.com/#docs/promise Promise 的含义 ...
    AI云栈阅读 4,361评论 0 7