2015-06-02 12 views
5

मैंने इस विषय पर बहुत सारे पोस्ट और बहुत से वेब लेख देखे हैं, और बहुत सारे वेब लेख हैं, लेकिन मैं अपनी समस्या से चिपक गया हूं। मुझे this post बहुत उपयोगी मिला लेकिन मेरा टाइमआउटRequest() फ़ंक्शन कभी नहीं कहा जा रहा है।

मैं $ http की टाइमआउट संपत्ति के साथ एक वादा का उपयोग कर रहा हूं लेकिन अंतर्निहित 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 अनुरोध को रोकता है।

अनुरोध रद्द करने का प्रयास करते समय एफ 12 (क्रोम) में कंसोल के साथ निरीक्षण से पता चलता है कि वादा का $$ राज्य 0 से 1 में बदल जाता है, इसलिए मुझे उम्मीद है कि वादा हल हो रहा है। हालांकि नेटवर्क यातायात में HTTP अनुरोध रद्द नहीं किया जा रहा है। HTTP अनुरोध पूरा होने तक मैं किसी अन्य पृष्ठ पर नेविगेट नहीं कर सकता।

क्या कोई मदद कर सकता है?

एम

+0

यदि आपका अनुरोध लंबे समय से ले रहा है, तो शायद मैं सर्वर पर एक बूलियन बनाउंगा, कह रहा हूं कि डेटा लोड/तैयार है, और यदि आप बूलियन सत्य हैं तो आप हर सेकेंड की जांच कर सकते हैं, डेटा वापस प्राप्त करें। यहां दो फायदे हैं: उपयोगकर्ता टाइमर को रद्द कर सकता है और डेटा तैयार करने से बच सकता है, ब्राउज़र लटका नहीं है। –

+0

मैं ऐसा नहीं कर सकता कि मुझे डर है। मैं एक सेवा बुला रहा हूं जिसके लिए मेरे पास स्रोत कोड नहीं है। – serlingpa

+0

आप $ scope.searchResults समझौते का वादा क्यों बचाते हैं? यदि आप इसे हटा देते हैं, तो क्या इससे मदद मिलती है? – Vlad274

उत्तर

7

क्या आप का वर्णन कर रहे हैं वास्तव में timeout संपत्ति का उपयोग कर एक $http अनुरोध रद्द करने का सही तरीका है। मैंने this Plunkr बनाया है जो आपके द्वारा प्रदान किए गए कोड के लिए जितना संभव हो सके इस व्यवहार को दिखाता है। आप देख सकते हैं कि जब "टाइमआउट के साथ अनुरोध सबमिट करें" बटन पर क्लिक किया जाता है तो अनुरोध सबमिट किया जाता है और 100 एमसीसी के बाद टाइमआउट वादा का समाधान किया जाता है (चूंकि अनुरोध इतना तेज़ हो जाता है कि आपके पास वास्तव में इसे रद्द करने के लिए कुछ क्लिक करने का समय नहीं है) :

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

$ http अनुरोध त्रुटि कॉलबैक प्रतिक्रिया की स्थिति की जाँच करता है और एक उचित त्रुटि संदेश है, जिसमें आप देख सकते हैं कि अनुरोध वास्तव में 100msec के बाद रद्द कर दिया गया प्रदर्शित करता है। आप अपने ब्राउज़र के डेवलपर टूल के नेटवर्क टैब में अनुरोध देखकर इसे सत्यापित भी कर सकते हैं।

$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.'; 
     } 
    }); 
    } 

उम्मीद है कि आप इसे अपने कोड में क्या गलत है और इसे सही करने के लिए उदाहरण के रूप में इसका उपयोग कर सकते हैं। अन्यथा कृपया कोड के साथ एक प्लंकर (या कुछ समान) बनाएं जो काम नहीं कर रहा है ताकि मैं आपकी मदद कर सकूं।

+0

ठीक है मैं एक प्लंकर बनाउंगा और यहां यूआरएल पोस्ट करूंगा। धन्यवाद। – serlingpa

+0

यह मुश्किल है क्योंकि HTTP अनुरोध बहुत जल्दी लौटाता है; मैं एक लंबे समय से चलने वाली सेवा कॉल की तलाश में हूं। – serlingpa

+0

ओके क्रिस्टीना, मैंने आपके प्लंकर को http://plnkr.co/edit/zhhYjyIZdNdUjYxHFn5U पर फोर्क किया है। यह सबसे सुंदर नहीं है लेकिन यह दर्शाता है कि यह वास्तव में काम करता है, इसलिए मुझे यह पता लगाना होगा कि मेरे कोड और इस सैंडबॉक्स कोड के बीच क्या अंतर है। – serlingpa

संबंधित मुद्दे