AngularJS调接口异步变同步处理

2019-07-16  本文已影响0人  刘越姐姐啊

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);
});

上一篇下一篇

猜你喜欢

热点阅读