Two more approaches
First, the newest async/await flow, promised based, also looklike sync flow
enabled in FF52+ and Chrome55+, works with FF , again failed with Chrome
And last one tested, the old (and good) worker aproach.
Works with FF (althought not so good), and also work well with Chrome (thank God !!!)
So, if you are stuck into the "callback hell", workers seems to be the last chance
But, one question remain: different behavior FF vs Chrome means different JS engine
implementation ? It seems like it means, because I did a test with the equivalent
messagebox and progressbar from another JS UI (Sencha ExtJS) and the results
are identically with EasyUI, exactly the same behavior.
Ok, these being said, I hope someone can find these tests useful, and I think this
topic can be closed, if there's nothing else to add.
Thanks to @jarry for help !
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Progress Messager</title>
<link rel="stylesheet" type="text/css" href="../../themes/default/easyui.css">
<link rel="stylesheet" type="text/css" href="../../themes/icon.css">
<link rel="stylesheet" type="text/css" href="../demo.css">
<script type="text/javascript" src="../../jquery.min.js"></script>
<script type="text/javascript" src="../../jquery.easyui.min.js"></script>
</head>
<body>
<h2>Progress Messager</h2>
<div id="p" class="easyui-panel" title="Messages" style="width:700px;height:200px;padding:10px;">
</div>
<div style="margin:20px 0;">
<a href="#" class="easyui-linkbutton" onclick="processAsync()">Async flow</a>
<a href="#" class="easyui-linkbutton" onclick="processSync()">Sync flow</a>
<a href="#" class="easyui-linkbutton" onclick="processGen()">Gen flow</a>
<a href="#" class="easyui-linkbutton" onclick="processAwait()">Await flow</a>
<a href="#" class="easyui-linkbutton" onclick="processWorker()">Worker flow</a>
</div>
<script type="text/javascript">
function showWaitMsg(message) {
var win = $.messager.progress({
title:'Please wait ...',
msg: message
});
}
function closeWaitMsg() {
var bar = $.messager.progress('bar');
$.messager.progress('close');
}
function changeProgressBar(index, max) {
var bar = $.messager.progress('bar');
var prval = Math.floor((10000 * index) / max)/100;
bar.progressbar('setValue', prval);
}
function loadPage(aurl, fCallback) {
var xhr = new XMLHttpRequest();
if(typeof fCallback === 'function') {
xhr.callback = fCallback;
function xhrSuccess () {
this.callback.apply(this, this.arguments);
}
xhr.onload = xhrSuccess;
}
xhr.open('get', aurl, false);
xhr.send();
}
function processSync() {
$('#p').html('');
$('#p').append('Start page processing<br>');
showWaitMsg('Processing pages ...');
setTimeout(function() {
for(var i=0; i<100; i++) {
changeProgressBar(i,100);
loadPage('/');
$('#p').append('Page: '+i.toString()+'<br>');
}
closeWaitMsg();
$('#p').append('Stop page processing <br>');
},1);
}
function processPage(i) {
setTimeout(function() {
changeProgressBar(i,100);
loadPage('/',
function() {
$('#p').append('Page: '+i.toString()+'<br>');
if(i<100) {
processPage(i+1); // recursion
} else {
closeWaitMsg();
$('#p').append('Stop page processing <br>');
}
}
);
},1);
}
function processAsync() {
$('#p').html('');
$('#p').append('Start page processing<br>');
showWaitMsg('Processing pages ...');
processPage(0);
}
function getPage(i) {
changeProgressBar(i,100);
loadPage('/');
$('#p').append('Page: '+i.toString()+'<br>');
}
function* getPages() {
var i=0;
while(i<100) {
yield getPage(i);
i++;
}
};
function runner(f) {
var fn = f();
var next = function (err, arg) {
if (err) return fn.throw(err);
var res = fn.next(arg);
if (res.done) return;
var func = res.value
if (typeof func == 'function')
func(next);
else
next(null, func);
}
next();
}
function processGen() {
$('#p').html('');
$('#p').append('Start page processing<br>');
showWaitMsg('Processing pages ...');
setTimeout(function() {
runner(getPages);
closeWaitMsg();
$('#p').append('Stop page processing <br>');
},1);
}
function processWorker() {
$('#p').html('');
showWaitMsg('Processing pages ...');
var worker = new Worker('worker.js');
var i = 0;
worker.onmessage = function (event) {
i++;
if(i<100) {
changeProgressBar(i,100);
$('#p').append('Page: '+i.toString()+'<br>');
} else {
closeWaitMsg();
$('#p').append('Stop page processing <br>');
}
};
}
function promisePage() {
return new Promise(resolve => {
loadPage('/');
});
}
async function getPromisePage() {
await promisePage();
}
function processAwait() {
$('#p').html('');
$('#p').append('Start page processing<br>');
showWaitMsg('Processing pages ...');
setTimeout(function() {
for(var i=0; i<100; i++) {
changeProgressBar(i,100);
getPromisePage();
$('#p').append('Page: '+i.toString()+'<br>');
}
closeWaitMsg();
$('#p').append('Stop page processing <br>');
},1);
}
</script>
</body>
</html>
worker.js
function loadPage(aurl, fCallback) {
var xhr = new XMLHttpRequest();
if(typeof fCallback === 'function') {
xhr.callback = fCallback;
function xhrSuccess () {
this.callback.apply(this, this.arguments);
}
xhr.onload = xhrSuccess;
}
xhr.open('get', aurl, false);
xhr.send();
}
for(var i=0; i<100; i++) {
loadPage('/');
postMessage(i);
}