Пример выполнения медленных расчетов на JavaScript в браузере с предотвращением появления окна с предложением остановить сценарий замедляющий работу веб-обозревателя:
function doSomething (callbackFunction [, additional arguments]) {
// Initialize a few things here...
(function startNextTimeout () {
// Do a little bit of work here...
if (termination condition) {
// We are done
callbackFunction();
} else {
// Process next chunk
setTimeout(startNextTimeout, 0);
}
})();
}
Этот паттерн можно немного модифицировать для того, чтобы он принимал функцию, отображающую прогресс выполнения длительной операции вместо функции, сообщающей о завершении длительной операции:
function doSomething (progressFunction [, additional arguments]) {
// Initialize a few things here...
(function startNextTimeout () {
// Do a little bit of work here...
if (continuation condition) {
// Inform the application of the progress
progressFunction(value, total);
// Process next chunk
setTimeout(startNextTimeout, 0);
}
})();
}
Пример страницы, отображающей прогрессбар выполнения длительной операции:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<title>Running long JavaScript processes in a web browser</title>
<style>
body {
padding:0;
margin:1em;
}
#progressbar {
position:relative;
width:300px; height:20px;
border:1px solid black;
overflow:hidden;
}
#progressbar div {
background:#316aC5;
width:0; height:100%;
}
</style>
</head>
<body>
<p>Sorting, please wait...</p>
<div id="progressbar"><div></div></div>
<script>
(function () {
var i, length, data, el, start;
// Initialize a few things...
length = 1000;
data = [];
el = document.getElementById('progressbar').firstChild;
// Setup an array of random integers...
for (i = 0; i < length; i++) {
data[i] = Math.floor(Math.random() * length);
}
function sort (progressFunction) {
i = 0;
(function startNextTimeout () {
var j, value;
for (j = length; j > i; j--) {
if (data[j] < data[j - 1]) {
value = data[j];
data[j] = data[j - 1];
data[j - 1] = value;
}
}
i++;
progressFunction(i, length);
if (i < length) {
setTimeout(startNextTimeout, 0);
}
})();
}
start = new Date().getTime();
sort(function (value, total) {
el.style.width = (100 * value / total) + "%";
if (value >= total) {
alert('Total duration: ' + ((new Date().getTime() - start) / 1000) + ' seconds');
}
});
})();
</script>
</body>
</html>
Пример последовательного выполнения задач по очереди:
function saveDocument(id){
var tasks = [openDocument, writeText, closeDocument, updateUI];
setTimeout(function startNextTask (){
//execute the next task
var task = tasks.shift();
task(id);
//determine if there's more
if (tasks.length > 0) {
setTimeout(startNextTask, 25);
}
}, 25);
}
Комментариев нет:
Отправить комментарий