JavaScript で重い処理を実行する時にUIに進捗表示しようと思ったのですが、JavaScriptではスレッドが扱えなかったりで結構ややこしいことをしないといけなかったため、ユーティリティー関数を用意しました。こちらに載せておきます。showProgressなどでjquery UIのプログレスバーなどを更新することでUIを更新することができます。
function startProgressiveProcess(
iterMax, // 繰り返し回数
mainProcess, // メイン処理
showProgress, // 進捗表示処理
onProcessFinished = null // 終了処理
) {
let iter = 0;
let endProcess = false;
setTimeout(function tmp() {
mainProcess(iter);
++iter;
showProgress(iter, iterMax);
if (iter < iterMax) {
setTimeout(tmp, 0);
}
else if (!endProcess) {
if (onProcessFinished != null) {
onProcessFinished();
}
endProcess = true;
}
}, 0);
}
以下はこちらの関数を使ってjquery UIのプログレスバーで進捗表示する簡易サンプルになります。
以下がこちらのサンプルのソースです。
<link type="text/css" rel="stylesheet" href="https://code.jquery.com/ui/1.10.2/themes/smoothness/jquery-ui.min.css" />
<script src="https://code.jquery.com/jquery-1.10.2.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jqueryui/1.12.1/jquery-ui.min.js"></script>
<input type="button" id="startProcessButton" value="処理を開始" /><br />
<div id="progress" style="height:10px"></div>
<script>
function startProgressiveProcess(iterMax, mainProcess, showProgress, onProcessFinished = null) {
let iter = 0;
let endProcess = false;
setTimeout(function tmp() {
mainProcess(iter);
++iter;
showProgress(iter, iterMax);
if (iter < iterMax) {
setTimeout(tmp, 0);
}
else if (!endProcess) {
if (onProcessFinished != null) {
onProcessFinished();
}
endProcess = true;
}
}, 0);
}
$("#progress").progressbar({
value: 0,
max: 10,
});
function sleep(waitMsec) {
var startMsec = new Date();
while (new Date() - startMsec < waitMsec);
}
$("#startProcessButton").click(function () {
startProgressiveProcess(
10,
function (iter) {
sleep(300);
},
function (iter, iterMax) {
$("#progress").progressbar({
value: iter,
max: iterMax,
});
},
function (iter, iterMax) {
$("#progress").progressbar({
value: 0,
max: 10,
});
});
});
</script>