繁体   English   中英

页面的JavaScript非阻塞更新

[英]JavaScript non-blocking updates to page

我有以下代码可以运行循环并随页面更新。 目前,直到整个循环运行完毕,页面才会更新。

如您所见,我尝试添加绘制函数drawValues ,该函数每5000次调用一次,以将当前值绘制到屏幕上。 我的理解是,当drawValues更新时,页面应该更新,然后主循环将继续其计算,直到另外5000循环。

目前,直到循环完全运行,页面才会更新,以某种方式忽略了对drawValues所有其他调用

完整摘要:

 /*jslint browser: true*/ /*global $, jQuery, alert*/ $(document).ready(function() { 'use strict'; var namesAtStart = ["Sam", "John"], specialNum = 8, amountOfNames = namesAtStart.length, counter = [], renderCounter = 0, x, a, loopLength, number, id, preId = "content_", finalId; for (a = 0; a < amountOfNames; a += 1) { counter.push(0); } for (x = 1; x <= specialNum; x += 1) { // Start the counter array at zero for (a = 0; a < amountOfNames; a += 1) { counter[a] = 0; } loopLength = Math.pow(10, x); finalId = preId + loopLength.toString(); $(".output-small").append('<span id="' + finalId + '"></span>'); for (a = 0; a < loopLength; a += 1) { number = Math.floor((Math.random() * amountOfNames) + 1); counter[number - 1] += 1; renderCounter += 1; if (renderCounter == 5000) { drawValues(namesAtStart, counter, finalId, x, a); } if (a == loopLength - 1) { // This is where I am trying to make the code non blocking and async drawValues(namesAtStart, counter, finalId, x, a); } } } }); // This is the part that I want to run when called and update page. function drawValues(names, counter, finalId, id, currentCount) { 'use strict'; var a; $("#" + finalId).empty(); $("#" + finalId).append("<h3>" + Math.pow(10, id).toLocaleString() + "</h1>"); for (a = 0; a < names.length; a += 1) { $("#" + finalId).append( names[a] + ": " + counter[a].toLocaleString() + " (" + (counter[a] / currentCount * 100).toFixed(2) + "%)</br>" ); } $("#" + finalId).append("Numerical Difference: " + Math.abs(counter[0] - counter[1]) + "</br>"); $("#" + finalId).append( "Percentage Difference: " + Math.abs( (counter[0] / currentCount * 100) - (counter[1] / currentCount * 100) ).toFixed(6) + "%</br>" ); $("#" + finalId).append("</br>"); } 
 body {} p, h3 { padding: 0px; margin: 0px; } .container {} .output {} .output-small { margin: 20px; padding: 5px; border: 1px solid rgba(0, 0, 0, 1); width: 300px; border-radius: 10px; } #stats-listing {} 
 <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <html> <head> <link rel="stylesheet" type="text/css" href="styles.css"> </head> <title>Roll The Dice</title> <body> <div class="container"> <div class="output" id="stats-listing"> <div class="output-small"></div> </div> </div> <script src="https://code.jquery.com/jquery-2.1.3.min.js"></script> <script src="logic.js"></script> </body> </html> 

浏览器中用于运行JavaScript的主UI线程是单线程。 因此,如果您使用的功能要花费大量时间,则浏览器不会更新显示内容。

为了使浏览器有机会更新显示,您需要让当前函数结束并通过setTimeout为下一个更新块安排定时回调到另一个运行,以便让浏览器恢复显示。 您必须尝试使用​​要支持的浏览器来确定定时回调中的延迟。 有些浏览器对0(尽快回叫)感到满意,而另一些浏览器则希望更长(50 – 50毫秒–对于我所知道的每个浏览器都足够)。

这是一个简单的示例,该示例向页面添加10个框,产生,然后再添加10个框,产生等等,直到完成1,000个框:

 (function() { var total = 0; addBoxes(); function addBoxes() { var n; for (n = 0; n < 10 && total < 1000; ++n, ++total) { box = document.createElement('div'); box.className = "box"; document.body.appendChild(box); } if (total < 1000) { setTimeout(addBoxes, 10); // 10ms } } })(); 
 .box { display: inline-block; border: 1px solid green; margin: 2px; width: 20px; height: 20px; } 

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM