2012-10-06 17 views
5

W3C spec का सुझाव देते हैं कार्यान्वयन निम्नलिखित: नेटवर्क पर एक XML दस्तावेज़ से डेटा के साथ कुछ लाए जाने क्या करने के लिए कुछ सरल कोड:क्या एक्सएचआर ट्रिगर ऑनस्टस्टेटेन्चेंज को कई बार तैयारस्टेट = डोन कर सकता है?

function processData(data) { 
    // taking care of data 
} 

function handler() { 
    if(this.readyState == this.DONE) { 
    if(this.status == 200 && 
     this.responseXML != null && 
     this.responseXML.getElementById('test').textContent) { 
     // success! 
     processData(this.responseXML.getElementById('test').textContent); 
     return; 
    } 
    // something went wrong 
    processData(null); 
    } 
} 

var client = new XMLHttpRequest(); 
client.onreadystatechange = handler; 
client.open("GET", "unicorn.xml"); 
client.send(); 

इस कार्यान्वयन वास्तव में सही है?

डीबग के दौरान मुझे ऐसे मामले मिलते हैं जब तैयारस्टेटेड ईवेंट हैंडलर को पंक्ति में एक से अधिक बार तैयार किया जाता है, उसी स्थिति के साथ == 4. मुझे लगता है कि यह व्यवहार सही है, क्योंकि चश्मा कहता है कि राज्य के प्रत्येक परिवर्तन को आग लगनी चाहिए घटना, और वह तैयारस्टेट हमेशा मौजूदा स्थिति के बराबर होना चाहिए, इसलिए यदि घटनाओं की कतार में कई घटनाएं ढीली होती हैं, तो यह स्पष्ट है कि किसी को तैयारस्टेट == 4.

http://jsfiddle.net/44b3P/ - यह है उपर्युक्त उदाहरण अनुरोध के बाद निष्पादन को रोकने के लिए डीबगर कॉल के साथ बढ़ाया गया है, और प्रक्रिया डेटा में चेतावनी() के साथ। एक बार जब आप निष्पादन को रोक दें तो आपको 3 अलर्ट मिलेंगे।

w3c से यह उदाहरण वेब पर कई स्थानों पर चिपकाया गया & कॉपी करता है - विशेष रूप से ओपनसामाजिक इस तरह xhr घटनाओं को संभालने लगता है। क्या यह सही है?

उत्तर

11

मैंने क्रोम डेवलपर टूल्स में डिबगिंग करते समय भी वही व्यवहार देखा (200 से अधिक बार मारा जा रहा है, यानी 2 ... n बार)।

यह रूप में अच्छी तरह डिबग मोड में हमेशा काम करने के लिए, मैं दो विकल्प मिल गया: एक XMLHTMLRequest W3C Spec

client.onload = हैंडलर की सफलता की पुष्टि करने के

  1. उपयोग onload;

    यह संस्करण IE8 में काम नहीं करेगा। यह एक ब्राउज़र को लागू करता है कि XMLHttpRequestEventTarget इंटरफ़ेस

  2. जैसे ही onreadystatechange हैंडलर निकालें के रूप में आप एक DONE 200 राज्य है होना चाहिए।

    client.onreadystatechange = function() { 
        // check if request is complete 
        if (this.readyState == this.DONE) { 
         if (this.onreadystatechange) { 
          client.onreadystatechange = null; 
          handler(); 
         } 
        } 
    }; 
    

मैं भी एक मुद्दा Chromium में इस समस्या के लिए, अच्छी तरह से खोल दिया उपलब्ध कराने के अपने Fiddle (धन्यवाद!)

+1

मूल रूप से प्रदान किए गए कोड का उपयोग करके - एक परिशिष्ट के रूप में, 'this.onreadystatechange = null;' पर्याप्त है, आपको XHR ('क्लाइंट') के मूल संदर्भ की आवश्यकता नहीं है। – Monchoman45

+0

जब मैंने 'xhr.onreadystatechange' हटाएं' का उपयोग करने का प्रयास किया, तो यह काम नहीं किया, इसे 'xhr.onreadystatechange = null' में बदलकर अच्छी तरह से काम किया। –

+0

मैंने इस समाधान डिन काम के लिए 'हटाएं' –

0

मैं था कभी नहीं किया है मेरी onreadystatechange हैंडलर की एक readyState 4.

मैं एक एकल निष्पादन संभालने लगता है पर किया सही है एक से अधिक बार मार डाला।

+1

, मेरे पास है। यह पुन: उत्पन्न करना काफी आसान है: http://jsfiddle.net/44b3P/ – qbolec

+0

हर बार जब मैं पृष्ठ को पुनः लोड करता हूं, तो केवल एक चेतावनी दिखाई देती है। (नवीनतम क्रोम) –

+0

समस्या केवल डीबग मोड में है (मैंने इसे केवल मैक पर परीक्षण किया है)। आपको डेवलपर टूल्स खोलना होगा और फिर पृष्ठ को फिर से लोड करना होगा। यह "निर्धारक" भी नहीं है (उपयोगकर्ता के लिए), क्योंकि कभी-कभी (शायद ही कभी) ऐसा नहीं होता है। मैं तर्क को समझ नहीं पाया कि इसे कितनी बार कहा जाता है। –