2016-06-11 8 views
6

मैं एक बाहरी स्क्रिप्ट लोड कर रहा हूं जो कॉलबैक फ़ंक्शन का उपयोग करता है, जो कुछ विशिष्ट डेटा देता है। यदि यह डेटा प्राप्त नहीं हुआ है तो त्रुटि प्रदर्शित की जानी चाहिए।जावास्क्रिप्ट ऑनलोड और स्क्रिप्ट कॉलबैक फ़ंक्शंस, जो प्राथमिकता लेता है?

<script> 
//setting initial state so that function will only work once 
var visitors_loaded=false; 
var my_callback = function(data) { 
    if (visitors_loaded) return 0; 
    if (data) { 
     //success: callback function is called and it has a proper data 
    visitors_loaded=true; 
    alert(JSON.stringify(data)); 
    } 
    else alert ('error'); //something went wrong 
}; 
</script> 
<script onload="my_callback(null)" onerror="my_callback(null)" 
src="https://api.clicky.com/api/stats/4?site_id=32020&sitekey=9a19b1a4d1171193&type=visitors&date=this-month&output=json&json_callback=my_callback"></script> 

आप देख सकते हैं ... बहुत सी बातें स्क्रिप्ट के साथ गलत हो सकता है कि, तो मैं स्वाभाविक रूप से एक onerror घटना कहा:

यहाँ कोड मैं कर दिया है है। यह त्रुटि घटना पर वास्तव में आग लगती है यदि आप स्क्रिप्ट के होस्ट नाम या डोमेन को किसी भी अस्तित्व में बदलते हैं।

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

अब समस्या, अगर सब सामान्य रूप से भरी हुई और डेटा नहीं दिया गया था, यह दोनों, कॉलबैक फ़ंक्शन और ऑनलोड आग जाएगा। मैंने देखा है कि ऑनलोड से पहले कॉलबैक फ़ंक्शन ट्रिगर किया गया है और विज़िटर_लोडेड वैरिएबल सेट किया गया है ताकि हैंडलर फ़ंक्शन को केवल एक बार बुलाया जा सके।

अभी तक यह जेएस फिडल और मेरी ऑफ़लाइन साइट में पूरी तरह से काम करता है लेकिन मुझे आश्चर्य है कि यह एक अपेक्षित व्यवहार है या नहीं? क्या json_callback फ़ंक्शन हमेशा ऑनलोड हैंडलर से पहले प्राथमिकता है?

https://jsfiddle.net/5sfk9ht5/4/

उत्तर

3

कि json_callback समारोह हमेशा ऑनलोड हैंडलर से पहले पूर्वता होगा?

यदि बाहरी स्क्रिप्ट my_callback तुल्यकालिक रूप से हाँ कहती है तो हाँ।

आधिकारिक html5 specification में scripting खंड वर्णन करता है कि इन बातों को काम करना होता है। विनिर्देश काफी सामान्य है और इसे एन्कोडिंग, सीओआरएस, ignore-destructive-writes counter और इसी तरह के कई विवरणों से निपटना होगा। लेकिन इस सवाल के लिए हमें इन विनिर्देशों की परवाह नहीं है।

नोट::

कदम वहाँ 4 में एक नोट है यह वह जगह है जहां स्क्रिप्ट संकलित किया गया है और वास्तव में मार डाला।

और चरण 7 load घटना में निकाल दिया जाता है:

आग एक सरल स्क्रिप्ट तत्व पर लोड नामित घटना।

तो विनिर्देश को परिभाषित करता है कि load घटना हमेशा के बाद स्क्रिप्ट के निष्पादित किया गया है निकाल दिया जाता है।


जैसा कि आप देख विनिर्देश भी हमें बताता है कि क्यों onerror घटना यदि आप URL बदल निकाल दिया नहीं है। error ईवेंट केवल तभी बनाया जाता है जब स्क्रिप्ट लोड हो जाती है। लेकिन सभी अनुरोध https://api.clicky.com/api/stats/ पर एक HTTP 200 स्थिति लौटाते हैं। अमान्य यूआरएल एक्सएमएल लौटाते हैं और इस तरह एक सिंटेक्स एरर फेंक दिया जाता है। लेकिन इससे onerror हैंडलर ट्रिगर होने का कारण नहीं बनता है।


अगर कॉलबैक कहा जाता है एसिंक्रोनस रूप से वे onload घटना के बाद अपने कॉलबैक कॉल कर सकते हैं के रूप में दूसरों का उल्लेख किया है। लेकिन मुझे कोई कारण नहीं दिख रहा है कि वे आपकी बाहरी लिपि में यह एसिंक क्यों करेंगे।

+1

अच्छा नमूना का जिक्र करते हुए! – Worthy7

2

अब समस्या है, अगर सब सामान्य रूप से भरी हुई और डेटा नहीं दिया गया था, यह दोनों, कॉलबैक फ़ंक्शन और ऑनलोड सक्रिय हो जाएगा। मैंने देखा है कि कॉलबैक फ़ंक्शन ऑनलोड से पहले ट्रिगर किया गया है और विज़िटर_लोडेड वैरिएबल सेट किया गया है ताकि हैंडलर फ़ंक्शन को केवल एक बार बुलाया जा सके।

इसका कारण यह है कॉलबैक api.clicky.com

अब तक यह जे एस बेला में पूरी तरह से काम करता है और मेरे ऑफ़लाइन साइट से बुलाया स्क्रिप्ट के भीतर से शुरू की है, लेकिन मुझे आश्चर्य है कि अगर यह एक उम्मीद है व्यवहार?

मैं देख रहा हूँ तुम क्या, क्या होता है जब एक स्क्रिप्ट विफल रहता है here है के बारे में संबंधित सवाल हो रही है, लेकिन मैं आप के लिए कुछ परीक्षण किया था और यहाँ के परिणाम हैं।

tester.html:

<script> 

var onLoadTest = function() { 
    console.log("Onload Called!"); 
}; 


var callbacktest = function() { 
    console.log("Called from other script!"); 
}; 

var errortest = function() { 
    console.log("Callback OnError!"); 
}; 

</script> 

<script onload="onLoadTest()" onerror="errortest()" 
src="script.js"></script> 

स्क्रिप्ट।js: कंसोल लॉग से

function otherScriptFunc() 
{  
    //call the function in the original script 
    callbacktest() 
} 

otherScriptFunc(); // first call to other script 
setTimeout(otherScriptFunc, 0); // final call to other script 

परिणाम

Called from other script! 
Onload Called! 
Called from other script! 
  1. आपका OnLoad बुलाया जाएगा जब अन्य जगह में जे एस पार्स किया जाता समाप्त हो गया है (async कार्यों के लिए अपने स्वयं करना होगा चीज़)। उदाहरण के लिए, otherScriptFunc();onload से पहले फोन करेगा लेकिन setTimeout(otherScriptFunc, 0); के बाद onload

  2. बुलाया जाएगा आपका OnError तभी GET अनुरोध त्रुटि है बुलाया जाएगा। आईई, फ़ाइल नहीं मिल सकती है, या यूआरएल हल नहीं किया जा सकता है - फाइल में क्या है इसके बारे में कुछ भी नहीं। (मैंने इसे अलग से परीक्षण किया, बस फ़ाइल नाम के साथ गड़बड़)

  3. जब भी दूसरी स्क्रिप्ट इस तरह महसूस होती है तो आपकी स्क्रिप्ट को अन्य स्क्रिप्ट में पास किया जा सकता है। इसका एक संदर्भ है और थोड़ी देर के लिए इसे पकड़ने का फैसला कर सकता है और इसे खेलने के बाद इसे बाद में कॉल कर सकता है। जिसका अर्थ यह है कि यह किसी अन्य डेटा के लिए इंतजार कर रहे एसिंक कॉल में हो सकता है। जिसका अर्थ है, सैद्धांतिक रूप से, आपका अधिभार वास्तव में कॉलबैक से पहले बुलाया जा सकता है, लेकिन यह दूसरी लिपि पर निर्भर करता है और इसके बारे में आप बहुत कुछ नहीं कर सकते हैं।

कि json_callback समारोह हमेशा ऑनलोड हैंडलर से पहले पूर्वता होगा?

यह प्राथमिकता के बारे में नहीं है, यह केवल तब निर्भर है जब दूसरी स्क्रिप्ट इसे कॉल करने का निर्णय लेती है। पुराने IE में

1

ऑनलोड आप 'onload' handler for 'script' tag in internet explorer के लिए काम नहीं कर सकते, यदि आप सभी ब्राउज़रों आप इस https://jsfiddle.net/e287523t/2/ की तरह कुछ जरूरत हो सकती है और सभी

 function addScript(fileSrc, callback) { 
     var head = document.getElementsByTagName('head')[0]; 
     var script = document.createElement('script'); 
     script.type = 'text/javascript'; 
     script.onreadystatechange = function() { 
      if (this.readyState == 'complete') { 
      callback(); 
      } 
     } 
     script.onload = callback; 
     script.src = fileSrc; 
     head.appendChild(script); 
    } 

लिए काम करना चाहिए तो फिर बाकी my_callback को परिभाषित करने और addScript बुला रहा है चलाना चाहते हैं

 my_callback = function(someData) { 
      alert(JSON.stringify(someData)); 
     }; 
संबंधित मुद्दे