मेरे पास एक लूप है जिसे ब्राउज़र में 200 मिलियन बार चलाने की आवश्यकता है। यह एक सिम्युलेटर है जिसे कई लोगों को नियमित रूप से उपयोग करने की आवश्यकता होती है। इसे चलाने में लगभग 15 मिनट लगते हैं, लेकिन इस समय के दौरान, ब्राउज़र अक्सर "इस स्क्रिप्ट में बहुत लंबा समय ले रहा है" के साथ एक चेतावनी पॉप अप करेगा, और यह फ़ंक्शन के दौरान फ़ायरफ़ॉक्स को पूरी तरह से लटकता है। इसका यह भी अर्थ है कि पृष्ठ मेरा स्टेटस इंडिकेटर अपडेट नहीं करता है (जो कि केवल एक संख्या है)।बड़े लूप पर ब्राउजर को लॉक करने से जावास्क्रिप्ट को रोकें
मैंने "जावास्क्रिप्ट उपज" गुगल किया है और हिट के पहले 4 पृष्ठ पढ़े हैं। कुछ नए "उपज" कीवर्ड पर चर्चा करते हैं, लेकिन केवल एक विवरण और उदाहरण है, जिसे मुझे समझ में नहीं आता है, उदा। "उपज कीवर्ड युक्त फ़ंक्शन एक जनरेटर होता है। जब आप इसे कॉल करते हैं, तो औपचारिक पैरामीटर वास्तविक तर्कों से बंधे होते हैं, लेकिन इसका शरीर वास्तव में मूल्यांकन नहीं किया जाता है"। यूआई को yield
उपज है? , http://www.julienlecomte.net/blog/2007/10/28/
हालांकि, ऊपर के उदाहरण किसी भी पाश चर या राज्य शामिल नहीं है:
कुछ समाधान मैं मिला में से एक इस पुराने पोस्ट जिसका बहिष्कार कॉल प्राप्त करने वाला तर्क का उपयोग करता है और खुद को कॉल करने के लिए एक टाइमर है और जब मैं इन्हें जोड़ता हूं तो यह अलग हो जाता है, और मेरा शुद्ध परिणाम हमेशा शून्य होता है।
यह भी चंकिंग नहीं करता है, लेकिन मुझे कुछ अन्य उदाहरण मिल गए हैं जो प्रत्येक पुनरावृत्ति पर "अनुक्रमणिका% 100 == 0" का उपयोग करके खंडित हैं। हालांकि, ऐसा करने का यह धीमा तरीका प्रतीत होता है। जैसे इस:
How to stop intense Javascript loop from freezing the browser
लेकिन यह प्रगति को अद्यतन करने के लिए किसी भी तरह नहीं है, और यूआई के लिए उपज नहीं है (ताकि अभी भी ब्राउज़र लटका हुआ है)।
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<script>
var spins = 1000000
var chunkSize = 1000;
var chunk;
function Stats() {this.a=0};
var stats = new Stats();
var big;
var index = 0;
var process = function() {
for (; index < spins; index++) {
stats.a++;
big = (big/3.6)+ big * 1.3 * big/2.1;
console.write(big);
// Perform xml processing
if (index + 1 < spins && index % 100 == 0) {
document.getElementById("result").innerHTML = stats.a;
setTimeout(process, 5);
}
}
document.getElementById("result").innerHTML = stats.a;
};
</script>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Untitled Document</title>
</head>
<body onload="process()">
<div id=result>result goes here.</div>
</body>
</html>
और यहाँ एक और प्रयास है जो stats.a
हमेशा शून्य है (तो मुझे लगता है कुछ scoping मुद्दा नहीं है):: यहाँ एक परीक्षण संस्करण है जो निष्पादन के दौरान ब्राउज़र लटका हुआ है
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<script>
var spins = 1000000
var chunkSize = 1000;
var chunk;
function Stats() {this.a=0};
var stats = new Stats();
function doIt() {
function spin() {
for (spinIx=0; (spinIx<chunkSize) && (spinIx+chunk < spins); spinIx++) {
stats.a++;
}
}
for (chunk =0; chunk < spins; chunk+=chunkSize){
setTimeout(spin, 5);
document.getElementById("result").innerHTML = stats.a;
}
document.getElementById("result").innerHTML = stats.a;
}
</script>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Untitled Document</title>
</head>
<body onload="doIt()">
<div id=result>result goes here.</div>
</body>
</html>
मैं इस काम को पाने के लिए 48 घंटे बिताए हैं - या तो मैं बहुत मूर्ख हूं या यह बहुत कठिन है। कोई विचार?
कई लोगों ने वेब श्रमिकों का सुझाव दिया है। मैंने अपना काम करने के लिए कई दिनों की कोशिश की, लेकिन मुझे एक ऐसा उदाहरण नहीं मिला जो एक संख्या उत्तीर्ण करता है। नीचे दिया गया कोड यह काम करने का मेरा आखिरी प्रयास था, लेकिन परिणाम हमेशा 0 होता है जब यह 100000 होना चाहिए। यह उसी तरह विफल रहता है जिस पर मेरा दूसरा उदाहरण विफल रहता है।
spinMaster.html:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
</head>
<body>
<script>
if(typeof(Worker)==="undefined") {
document.write("<h1>sorry, your browser doesnt support web workers, please use firefox, opera, chorme or safari</h1>");
}
var worker =new Worker("spinWorker.js");
worker.postMessage({times:1000000});
worker.onmessage=function(event){
document.getElementById("result").innerHTML=event.data;
};
</script>
<div id="result">result goes here</div>
</body>
</html>
spinWorker.js
function State() {
this.a=0;
}
var state = new State();
self.addEventListener('message', spin, false);
function spin(e) {
var times, i;
times = e.data.times;
//times = 1000000; // this doesnt work either.
for(i;i<times;i++) {
state.a++;
}
self.postMessage(state.a);
}
परिणामी उत्पादन: 0
के बाद से जे एस है एक लड़ी आमतौर पर, मुझे नहीं लगता कि यह चारों ओर किसी भी तरह से है। यदि आप केवल नए ब्राउज़र का समर्थन कर रहे हैं, तो हो सकता है कि आप वेब श्रमिकों को देखना चाहें, जो काम करने के लिए एक नया धागा पैदा कर सकते हैं: https://developer.mozilla.org/en-US/docs/DOM/Using_web_workers – kennypu
@kennypu आपको इसे एक उत्तर के रूप में पोस्ट करना चाहिए। –
आपकी प्रदर्शन समस्या लगातार डीओएम हेरफेर (हर 5 एमएमएस) हो सकती है, जो बहुत महंगा है। डीओएम को एक अलग दर पर अपडेट करने का प्रयास करें, हर 10-20 सेकंड कहें और देखें कि क्या यह बेहतर/तेज़ प्रदर्शन करता है। – elclanrs