2015-11-26 8 views
14

मैं इस कोड है जो कहते हैं "हाय" जब मैं "हैलो" बटन पर क्लिक करें माना जाता है लिखा है:जावास्क्रिप्ट प्रिंट नहीं करता पाठ तुरंत

<!DOCTYPE html> 

<html> 

<head> 
<script> 
var someLargeNumber = 5000000000; 
function hello() { 
    document.getElementById('hi').innerHTML = "hi"; 
    for(var i = 0; i < someLargeNumber; i++) {} 
} 
</script> 
</head> 

<body> 
<p id="hi"></p> 
<input type="button" value="hello" onclick="hello();"> 
</body> 

</html> 

यह नमस्ते कहने करता है, लेकिन बाद ही for पाश समाप्त हो गया है । ऐसा क्यों होता है और मैं इसे कैसे ठीक करूं?

धन्यवाद

+3

शायद तुम पाश बाहर ले सकता है। यह वहाँ क्यों है? जब तक "क्लिक" हैंडलर समाप्त नहीं हो जाता तब तक ब्राउज़र पृष्ठ को फिर से प्रस्तुत नहीं करेगा (जरूरी)। – Pointy

उत्तर

23

ऐसा क्यों होता है ...

चूंकि ब्राउज़र मुख्य यूआई धागा वे कई कारणों से के लिए, पृष्ठ को अपडेट करने के लिए उपयोग पर JavaScript चला। इसलिए यद्यपि आपने "हाय" टेक्स्ट दिखाया है, फिर भी यह पूरा नहीं होता है जब तक कि ईवेंट पूरा होने के जवाब में जावास्क्रिप्ट कोड चल रहा हो।

... और मैं इसे कैसे ठीक करूं?

टेक्स्ट जोड़ने के बाद ब्राउजर पर वापस जाएं, ऐसा करने से पहले कि आप उस लूप के साथ अनुकरण कर रहे हैं। setTimeout0 की देरी के साथ कई मामलों के लिए उपयुक्त है:

var someLargeNumber = 5000000000; 
function hello() { 
    document.getElementById('hi').innerHTML = "hi"; 
    setTimeout(function() { 
     for(var i = 0; i < someLargeNumber; i++) {} 
    }, 0); 
} 

JavaScript इंजन एक कार्य कतार के साथ एक पाश में मूल रूप से काम करता है (कल्पना उन्हें "नौकरियों" कॉल)। यह कतार से नौकरी उठाता है, इसे पूरा करने के लिए चलाता है, और फिर अगली नौकरी की तलाश करता है। जब ब्राउज़र नौकरियों के बीच होता है तो ब्राउज़र्स (आमतौर पर) यूआई को अपडेट करते हैं। जब कोई घटना होती है, तो इवेंट हैंडलर को कॉल करने के लिए नौकरी कतारबद्ध होती है। उपर्युक्त बस लूप को setTimeout के माध्यम से कतार में एक नई नौकरी में ले जाता है, इसलिए ब्राउज़र को ईवेंट नौकरी के बाद और यूआई को अपडेट करने के लिए setTimeout नौकरी के बाद एक मौका है।

+0

[संबंधित प्रश्न/उत्तर] (http://stackoverflow.com/questions/779379/why-is-settimeoutfn-0- कभी-कभी उपयोगी) 'setTimeout (fn, 0);' पैटर्न को समर्पित –

0

जैसा कि पहले से ही उत्तर दिया गया ब्राउज़र में एकल UI थ्रेड है।

एक और विकल्प Web Worker का उपयोग करना है (बशर्ते आप कार्यकर्ता धागे में कोई भी डोम मैनिप्लेशंस नहीं कर रहे हैं), जो एक और धागे में संचालन चलाने की अनुमति देता है।

मुख्य फ़ाइल आप में एक और जे एस फ़ाइल (जैसे कि worker.js)

var someLargeNumber = 5000000000; 
onmessage = function(e) { 
    console.log('Message received from main script'); 
    for(var i = 0; i < someLargeNumber; i++) {} 
    console.log('Posting message back to main script'); 
    postMessage('done'); 
} 

जोड़े वापस

<head> 
<script> 
var myWorker = new Worker("worker.js"); 
function hello() { 
    document.getElementById('hi').innerHTML = "hi"; 
    myWorker.postMessage('test'); 
    console.log('Message posted to worker'); 
} 
myWorker.onmessage = function(e) { 
    result.textContent = e.data; 
    console.log('Worker thread is complete'); 
} 
</script> 
संबंधित मुद्दे