2015-06-02 41 views
5

我已經看過很多很多關於此主題的帖子和大量的網絡文章,但我仍然難以解決我的問題。我發現this post非常有用,但我的timeoutRequest()函數永遠不會被調用。

我正在使用$ http的timeout屬性的承諾,但底層的HTTP請求未被取消。我認爲承諾本身正在得到解決,但請求並未取消。

我的控制器的行爲看起來是這樣的:

$scope.enquiriesSelected = function() { 
    $scope.cancelHttpRequests(); 
    $location.path("/enquiries"); 
}; 

$scope.cancelHttpRequests = function() { 
    console.log(canceller.promise.$$state); 
    canceller.resolve("User cancelled"); 
    console.log(canceller.promise.$$state); 
}; 

我的HTTP請求,承諾如下:

var canceller = $q.defer(); 

$scope.searchResultsPromise = $http({ 
     url: "/api/customers/customersearch", 
     method: "POST", 
     data: criteria, 
     timeout: canceller.promise 
    }) 
    .success(function(data) { 
     $scope.customerSearchResults = data; 
    }); 

我已經嘗試了各種方法來得到這個工作,包括把消除在$範圍。

我一直在尋找通過AngularJS源代碼,我發現這些行:

if (timeout > 0) { 
    var timeoutId = $browserDefer(timeoutRequest, timeout); 
} else if (isPromiseLike(timeout)) { 
    timeout.then(timeoutRequest); 
} 

function timeoutRequest() { 
    jsonpDone && jsonpDone(); 
    xhr && xhr.abort(); 
} 

然而,當我的承諾,解決執行路徑沒有達到這些行。 xhr.abort()永遠不會被調用,這是AngularJS源代碼中放棄HTTP請求的唯一地方。

嘗試取消請求時,使用F12(Chrome)中的控制檯進行檢查顯示承諾的$$狀態從0更改爲1,因此我相當確信承諾正在解決。但是,在網絡流量中,HTTP請求未被取消。在HTTP請求完成之前,我無法導航到其他頁面。

任何人都可以幫忙嗎?

中號

+0

如果您的請求花費很長時間,我可能會在服務器端創建一個布爾值,表示數據已加載/準備就緒,並且如果布爾值爲true,則可以檢查每一秒,然後獲取數據。這裏有兩個優點:用戶可以取消定時器,並避免檢查數據準備好,瀏覽器不會掛起。 –

+0

我不能那樣做,我害怕。我打電話給我沒有源代碼的服務。 – serlingpa

+0

爲什麼您將承諾保存到$ scope.searchResultsPromise?如果你刪除它,這有幫助嗎? – Vlad274

回答

7

你所描述實際上是取消使用timeout財產$http請求的正確方法。我創建了this Plunkr,其中顯示此行爲儘可能接近您提供的代碼。您可以看到,當點擊「提交超時提交請求」按鈕時,會提交一個請求,超時承諾將在100毫秒後解決(因爲請求返回非常快,您沒有時間點擊某些內容來取消它) :

$scope.requestWithTimeout = function() { 
    $timeout(function(){canceller.resolve("User cancelled");}, 100); 
    $scope.submitRequest(); 
} 

的$ HTTP請求錯誤回調檢查響應的狀態,並顯示相應的錯誤信息,在此您可以看到,請求100毫秒後實際取消。您還可以通過觀察瀏覽器開發人員工具的網絡選項卡中的請求來驗證此情況。

$scope.submitRequest = function() { 
    // Reset the canceler promise 
    canceller = $q.defer(); 
    $scope.status = 'Request submitted'; 
    var startTime = (new Date()).getTime(); 
    $http({ 
     url: 'style.css', 
     method: 'GET', 
     timeout: canceller.promise 
    }) 
    .success(function(data) { 
     var endTime = (new Date()).getTime(); 
     $scope.status = 'Request response returned after ' + (endTime - startTime) + ' msec.'; 
    }) 
    .error(function(data, status) { 
     var endTime = (new Date()).getTime(); 
     if(status === 0) { 
     $scope.status = 'Request timed out after ' + (endTime - startTime) + ' msec.'; 
     } else { 
     $scope.status = 'Request returned with error after ' + (endTime - startTime) + ' msec.'; 
     } 
    }); 
    } 

希望你可以用這個爲例來找出你的代碼出了什麼問題並改正它。否則,請使用不工作的代碼創建一個Plunkr(或類似的東西),以便我可以進一步提供幫助。

+0

好的,我將創建一個Plunkr並在此處發佈URL。謝謝。 – serlingpa

+0

這很難,因爲HTTP請求很快返回;我正在尋找長時間的服務電話。 – serlingpa

+0

好的克里斯蒂娜,我在http://plnkr.co/edit/zhhYjyIZdNdUjYxHFn5U分叉你的Plunkr。這不是最漂亮的,但它確實證明它確實可以工作,所以我必須弄清楚我的代碼和這個沙盒代碼之間有什麼不同。 – serlingpa