Chain Angular $ http调用正常吗?

VSO*_*VSO 17 angularjs angular-promise

我现在已经阅读了大约$ q和承诺几天了,我似乎也明白了...... 我在实践中遇到以下情况:

  1. 发出$ http请求并检查是否可以进行后续调用.
  2. 如果第一次呼叫失败,则返回"无数据",如果成功并表示可以进行呼叫,则进行第二次呼叫,如果不​​成功,则再次进行"无数据".如果第二次调用成功,则返回数据,如果不是 - "无数据".它看起来像这样(大约,我简化了一般的想法,所以不要担心这里的小错误):

            return $http.get (something)
                .then(function(allowedAccess){
                    if(allowedAccess){
                        return $http.get (somethingElse)
                            .then( function(result){return {data:result} },
                            function(error){return {data:"n0pe"} }
                        )
                    } else {
                        return {data:"n0pe"}
                    }
                },
                function(){ return {data:"n0pe"} });
    
    Run Code Online (Sandbox Code Playgroud)

有人告诉我在这里使用$ q.我真的不明白我会怎样或为什么.$ http电话已经是承诺.

如果有办法使这个更清洁,我没有看到它.刚刚完成了关于这个主题的重新阅读这篇文章.基本上,我错过了什么/有没有更好的方法来做到这一点?

编辑:也只是重新阅读链接承诺的教程 - 它根本不处理呼叫失败.基本上将此作为尽职调查发布.

编辑2:这更详细地阐述了我要问的理论,摘自第一篇文章:

这是一个简单的例子.如果你的then()回调返回另一个promise,它会变得非常强大.在这种情况下,下一个then()只会在承诺结算后执行.例如,此模式可用于串行HTTP请求(请求取决于前一个请求的结果):

这似乎是在谈论像这样的链:

   asyncFn1(1)
    .then(function(data){return asyncFn2(data)})
    .then(function(data){return asyncFn3(data)})
Run Code Online (Sandbox Code Playgroud)

所以,如果我理解正确这一点a).不适用于我,因为我没有第三功能.B).如果我有三个函数会适用于我,因为当我在第一个$ http请求中运行if语句时,只有在if语句中我才会返回另一个promise.所以,理论上,如果我有三个异步函数来链接,我需要将我的if语句放在一个promise中吗?

New*_*Dev 13

Promise确实有助于进行异步调用的代码组合.换句话说,它们允许您以类似于组成同步调用集的方式(使用链接.thens)以及同步代码位于try/ catchblock(with .catch)中的方式编写代码.

所以,想象一下你的HTTP调用是阻塞的 - 你的逻辑看起来是这样的:

var allowedAccess, data;
try {
  allowedAccess = $http.get(something);

  if (allowedAccess){
    try{
      var result = $http.get(somethingElse);
      data = {data: result};
    } catch (){
      data = {data: "n0pe"};
    }
  } else {
    data = {data: "n0pe"};
  }
} catch (){
  data = {data: "n0pe"};
}
return data;
Run Code Online (Sandbox Code Playgroud)

你可以简化一下:

var allowedAccess, result;
try {
  allowedAccess = $http.get(something);
  var result;
  if (allowedAccess) {
     result = $http.get(somethingElse);
  } else {
     throw;
  }
  data = {data: result};
} catch () {
   data = {data: "n0pe"};
}
return data;
Run Code Online (Sandbox Code Playgroud)

这将转换为异步版本:

return $http
          .get(something)
          .then(function(allowedAccess){
             if (allowedAccess){
               return $http.get(somethingElse);
             } else {
               return $q.reject(); // this is the "throw;" from above
             }
          })
          .then(function(result){
             return {data: result};
          })
          .catch(function(){
             return {data: "n0pe"};
          })
Run Code Online (Sandbox Code Playgroud)

至少,这是在使用分支和异步调用编写代码时可以应用的原因.

我不是说我提出的版本是最优的或者更短-这然而,更干,因为一个错误处理.但是要意识到,当你这样做时,.then(success, error)它等同于try/ catch超过之前的异步操作 - 根据你的具体情况,这可能需要也可能不需要.


Mat*_*Way 7

这就是我编写这类问题的方法:

// returns a promise that resolves some endpoint if allowed
function getDataWithAccess(allowed){
    return allowed ? $http.get(someEndpoint) : $q.reject();
}

// do something with data
function handleData(data){
    // do stuff with your data
}

// main chain
$http.get(accessCredEndpoint)
    .then(getDataWithAccess)
    .then(handleData)
    .catch(function(err){
        return { data: "n0pe" };
    });
Run Code Online (Sandbox Code Playgroud)

是的,这非常像New Dev的答案,但是我想要将功能提取到他们自己的块中.这使整个代码更具可读性.