2015-05-05 36 views
4

我必須依次執行三個不同的$ http-calls,它們相互依賴。到現在爲止我工作的解決方案IST像這樣

$http.get(".../1/...").success(function(){ 
    $http.get(".../2/...").success(function(){ 
     $http.get(".../3/...").success(function(){ 

     }); 
    }); 
}); 

現在有要做出一定的改變:如果條件爲true,第一個電話應該被跳過。我可以這樣做:

if(skipCallOne) { 
    $http.get(".../2/...").success(function(){ 
     $http.get(".../3/...").success(function(){ 

     }); 
    }); 
} else { 
    $http.get(".../1/...").success(function(){ 
     $http.get(".../2/...").success(function(){ 
      $http.get(".../3/...").success(function(){ 

      }); 
     }); 
    }); 
} 

這顯然會導致大規模的代碼複製。我發現如果我使用propper函數進行特定的$ http-calls,這可能會減少。但據我瞭解一個更好的解決辦法是使用和正確鏈中的$ HTTP的承諾,像這樣:

$http.get(".../1/...").then(function(){ 
    return $http.get(".../2/..."); 
}).then(function() { 
    return $http.get(".../3/..."); 
}).then(function() { 

}); 

但現在我的問題是,我怎麼能conditionaly跳過用最少的代碼複製第一個電話?

回答

10

你可以試試這個方法:

$q.when(skipCallOne || $http.get(".../1/...")) 
    .then(function() { 
    return $http.get(".../2/..."); 
    }).then(function() { 
    return $http.get(".../3/..."); 
    }).then(function() { 
}); 
+0

這看起來很像的東西我希望看到的。但是我不確定是否理解使用$ http.get(...)。你不打電話,爲什麼? –

+1

在這裏完全同意你的意見。我編輯了我的答案。我們來看一下這個文檔:.when(value)將一個可能是一個值的對象或者一個(第三方)包裝成一個$ q promise。當你處理可能或不可能成爲承諾的對象時,或者承諾來自不可信任的來源時,這很有用。 –

4

你可以用在測試條件功能$http.get調用,如果報考條件或預解析的承諾,如果無法返回$http.get承諾。

function callOne() { 
    if(condition) { 
     return $http.get(".../1/..."); 
    } else { 
     var deferred = $q.defer(); 
     deferred.resolve(); 
     return deferred.promise; 
    } 
} 

callOne().then(function() { 
    return $http.get(".../2/..."); 
}) 
+1

其實我覺得@PhilippAndreychev的解決方案比較好,因爲它比較習慣q。 –

1

我喜歡能夠看到這樣的東西的工作,所以我把這個微控制器一起展示的承諾解決,是有條件$ http.get首先運行。我不認爲這是優雅的或者與其他答案一樣聰明,儘管我認爲它與克里斯蒂安的解決方案非常相似。

注:一兩件事,可能使這種費解的是,這個問題的答案常表現鏈接$ HTTP調用這些僅執行,爲了簡便起見,這些調用的返回值被忽略,它可能不會立即清楚如何將事情分開以實現價值。

Demo

app.controller('MainCtrl', function($scope, $q, $http) { 
    $scope.x = true; 

    var firstHttp = function() { 
    var deferred = $q.defer() 
    if($scope.x) { 
     data = 'x was true' 
     deferred.resolve(data); 
    } else { 
     $http.get('test.json') 
     .then(function(data) { 
     $scope.data1 = data; 
     deferred.resolve(data); 
     }) 
    } 
    return deferred.promise 
    } 

    $scope.myGetterFn = function() { 
    firstHttp() 
    .then(function(data) 
    { 
     data.data ? $scope.data1 = data : $scope.datax = data; 
     $http.get('test2.json') 
    .then(function(data2) 
    { 
     $scope.data2 = data2 
     $http.get('test3.json') 
    .then(function(data3) 
    { 
      $scope.data3 = data3 
    }) 
    }) 
    }) 
    } 
});