我正在创建一个简单的异步进程帮助程序 - 对于某些解析,最好使其更慢并防止浏览器无响应。
“helper”类需要2个必要的参数 - 将执行任务的工作线程函数,无论它是什么以及变量,它们将通过迭代持续存在并最终由工作线程更改。例如。 解析文本,进度或其他。
现在,最简单的方法是使用对象或数组:
ProgressManager(task, taskdata) {
...
tick() {
...
task(taskdata);
}
...
}
var progress = new ProgressManager(function(data) {data.ticks++;}, {ticks: 0});
对于taskdata
是一个对象实例,引用传递给task
。但是,我对此并不满意。如果我可以模拟这样的论点,那将会更好:
ProgressManager(task, taskdata) {
var arguments = new ArgumentsObjectThatDoesNotExistAsFarAsIKnow();
//Create some fake named arguments
for(var i in taskdata) {
arguments.add(i, taskdata.i);
}
...
tick() {
...
task.useArguments(arguments);
}
...
}
var progress = new ProgressManager(function(ticks) {ticks++;}, {ticks: 0});
我不介意在task
函数中预定义的参数。
这是全班,现在似乎工作(使用referecnes):
/**
@arguments
task - the function that will be performed every iteration MUST RETURN ProgressEvent instance
taskdata - variables for the class - an object, or array so it persists and is passed as a reference
onFinish - function that will be called when progress is over
onProgress - this will be called every iteration
*
*
**/
function ProgressManager(task, taskdata, onFinish, onProgress) {
//Save the arguments
this.onProgress = onProgress;
this.onFinish = onFinish;
this.onError = null;
this.onPause = null;
//Speed control variables
this.sleep = 20;
//Progress variables
var running = 0; //0 - stoped, 1-running, 2 - paused
this.progress = null;//Percent of progress if any - not used yet
//Self reference for callbacks
var _this = this;
//Now the progress methods
this.start = function() {
if(running==1)
return;
running = 1;
heart();
}
this.resume = function() {
this.start();
}
this.stop = function() {
running = 0;
//This triggers an error too
error({type:"Cancelled"});
}
//This ticks and calls task
function heart() {
if(running!=1)
return;
setTimeout(function() {tick();}, _this.sleep);
}
//This happens on every heartbeat
function tick() {
var evt = task(taskdata);
if(typeof evt=="undefined"||evt==null||!(evt instanceof ProgressEvent)) {
error({type:"Invalid event.", data:evt});
}
if(evt.isFinished) {
finished();
return;
}
else if(evt.progress>90) {
console.log(evt);
}
if(evt.isError) {
error({type:"Progress error", data:evt.error});
}
if(typeof _this.onProgress == "function") {
_this.onProgress(evt);
}
heart();
}
//This is trigerred when job is done
function finished(evt) {
running = 0;
//Trigger event
if(typeof _this.onFinish == "function") {
_this.onFinish(evt);
}
}
//This will handle errors
function error(err) {
_this.stop();
if(typeof _this.onError == "function")
_this.onError(err);
if(console!=null&&console.error!=null) {
console.error("Error happened during progress: ",err);
throw null;
}
else
throw new Error("Error happened during progress: "+ err.type);
}
}
function ProgressEvent(finished, error, progress) {
if(progress>=100)
finished=true;
this.isFinished = finished===null?false:finished;
this.isError = error===null?false:error;
this.progress = progress;
}