2015-09-22 70 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() {…});