2015-09-22 72 views
0

我希望能够链接承诺,以使代码同步。我的问题是,根据第一个$ http请求的结果,我可能想要发送另一个或不。 如果我选择不发送另一个$ http请求,我不需要我的第二个then()来做任何事情。但由于我的第二个then()不知道这一切,它仍然挂在那里,所以我想我需要从第一个回来,然后一些假虚拟承诺。但是我还想在第二时间()中认识到这种情况。我想出了从第一种情况返回$ q.when('一些值')。下面是代码:如何从.then返回承诺

$http.get(url, params) 
    .then(function(res) { 
     res = res.data; 
     if (res.status == 'ok' && res.rows.length > 0) { 
      $scope.roomTypes = res.rows; 
      return $q.when({ isDummy: true }); //in this case I don't need to send another request 
     } else if (res.rows.length === 0 && $scope.request.roomType) { 
      return $http.get(url2, params2); //make second request and return then`able promise 
     } 
    }, function(res) { 
     throw 'Error'; 
    }) 
    .then(function(res) { 
     res = res.data; 
     if (res.status == 'ok') { 
      var roomType = { 
       room_type: res.roomType.id, 
       description: res.roomType.description 
      }; 
      $scope.roomTypes.push(roomType); 
     } else if (res.isDummy) { 
      //ok that's our dummy promise 
     } else { 
      //format of response unexpected it means something went wrong 
      throw "error"; 
     } 
    }, funcrtion(res) { 
     throw "some Error"; 
    }) 
    .catch(function(res) {...}) 
    .finally(function() {...}); 

是我希望看到与承诺就解决了价值的东西({isDummy:真}),但我怎么做呢?我在res参数中获得undefined

+0

有一个在你的代码一个错字:'funcrtion' – rmorrin

回答

1

res会在这里,因为没有data财产上{isDummy: true}对象是不确定的

 .then(function(res) { 
     res = res.data; 
     ... 

+0

'res.data'应该是未定义的。但'res'本身不应该。 – rmorrin

+0

它被分配给'res.data'。因此,这个问题。 – estus

+0

@rmorrin,estus你是我的英雄! – dKab

0

尝试返回除承诺或延期以外的任何对象:)并将其值传递给then。像这样:

return { isDummy: true }; 

示例代码:https://jsfiddle.net/817pwvus/

从jQuery的whendocumentation

如果单个参数被传递给jQuery.when(),并且它不是一个延迟或无极,它将被视为已解决的延迟,任何已完成的附加回调将立即执行。 doneCallbacks传递了原始参数。

0

如果你想要代码同步,你可以随时在第一个代码块中写一个长代码块。

,如果你想链的承诺(邮编:URL1) - >(邮编:URL2)等:

1.回报是没用的。 2.假设你有2 $ HTTP承诺要链条,无论是从一种名为$用户,例如,他们叫GetUserAge和GetRelevantBars和第二查询基于第一个的结果。

angular 
.module("moduleA") 
.controller("exmapleCtrl",exampleCtrl); 

exampleCtrl.$injector=["$users"]; 

function exampleCtrl($users){ 
var vm=this; 

vm.query = $users.GetUserAge().then(/*OnSuccess*/ GetUserAgeCB) 

//Callback of the GetUserAgeCB; 
function GetUserAgeCB(result){ 
    $users.GetRelevantBars().then(/*OnSuccess*/ GetRelevantBarsCB); 
    /*continuation of CallBack code*/ 
} 


//Callback of the GetRelevantBarsCB; 
function GetRelevantBarsCB(result){ 
    /*CallBack code*/ 
} 

} 

希望这是可以理解的..

1

我认为这里的基本问题是混乱的承诺与承诺处理。成功处理程序应该返回一个值,而不是另一个承诺。当你在一个承诺成功处理程序中时,你被承诺机制“包装”,它将你的返回值传递给下一个处理程序。这意味着你的第二个承诺没有看到最初的回应,但是第一个承诺返回的是什么。

,因为它去沿,除非你把它当作是被处理的值。

例如 这一切都与您的线

return $q.when({isDummy: true}); 

应该

return {isDummy: true}; 

的问题是另一种情况下,要继续到下一个查询。我可能会执行以下任一操作: 1.从第一个承诺开始处理(使用第一个处理程序的相关逻辑)。 2.通过url2和params - return({url:url2,params:params})并在第二个承诺中处理它们。

注意承诺chanins甚至可以在中间断开,如果任何处理程序拒绝,将不会调用成功处理程序here is a simple example(确保打开devtools控制台以查看日志)。

0

,而不是返回一个虚拟值,并忽略了显式,你更应该巢和第二处理程序附加只需要承诺的那样:

$http.get(url, params) 
.then(function(res) { 
    var data = res.data; 
    if (data.status == 'ok' && data.rows.length > 0) { 
     $scope.roomTypes = data.rows; 
     return; // do nothing 
    } else if (res.rows.length === 0 && $scope.request.roomType) { 
     return $http.get(url2, params2) 
     .then(function(res) { 
      var data = res.data; 
      if (data.status == 'ok') 
       $scope.roomTypes.push({ 
        room_type: data.roomType.id, 
        description: data.roomType.description 
       }); 
      else 
       throw "error"; //format of response unexpected it means something went wrong 
     }); 
    } 
}) 
.catch(function(res) {…}) 
.finally(function() {…});