welsonjs/lib/task.js
2021-06-25 03:43:54 +09:00

206 lines
4.2 KiB
JavaScript

//////////////////////////////////////////////////////////////////////////////////
// Task API (Time-sharing based `async`, `setTimeout`, `setInterval`, `Promise` implementation in WSH.js)
/////////////////////////////////////////////////////////////////////////////////
/* // example:
* // var TASK = require("lib/task");
* // var taskQueue = TASK.createTaskQueue();
* // TASK.putTask(queue, function() { console.log('123'); sleep(100); }, [1, 2, 3])
* // .then(TASK.createTask(function() { console.log('456'); sleep(200); }, [4, 5, 6]))
* // .then(TASK.createTask(function() { console.log('789'); sleep(300); }, [7, 8, 9]))
* // ;
* // TASK.putTask(queue, function() { console.log('321'); sleep(100); }, [3, 2, 1])
* // .then(TASK.createTask(function() { console.log('654'); sleep(200); }, [6, 5, 4]))
* // .then(TASK.createTask(function() { TASK.stop(); console.log('987'); sleep(300); }, [9, 8, 7]))
* // ;
* // taskQueue.run();
*/
var Task = function(f, params, when) {
this.f = f;
this.params = params;
this.nextTask = null;
this.when = (typeof(when) === "number" ? when : 0);
this.setNextTask = function(task) {
this.nextTask = task;
};
};
var TaskQueue = function() {
this._task = null;
this._keepalive = true;
this.queue = [];
this.put = function(task) {
try {
this._task = task;
this.queue.push(this._task);
} catch(e) {
console.error("TaskQueue.put exception: " + e.message);
}
return this;
};
this.get = function() {
var task = null;
//var now = new Date().getTime();
//var delta = now;
try {
if (this.queue.length > 0) {
/*
var k = 0;
for (var i = 0; i < this.queue.length; i++) {
var _delta = now - this.queue[i].when;
if (delta > _delta) {
k = i;
delta = _delta;
}
}
task = this.queue[k];
this.queue = this.queue.splice(k, 1);
*/
task = this.queue[0];
this.queue = this.queue.slice(1);
}
} catch(e) {
console.error("TaskQueue.get: " + e.message);
}
return task;
};
this.next = function() {
var result = null;
try {
var task = this.get();
if (task != null) {
try {
result = task.f.apply(null, task.params);
} catch (e) {
console.error("Task exception: " + e.message);
}
if (task.nextTask != null) {
this.put(task.nextTask);
}
}
} catch(e) {
console.error("TaskQueue.next: " + e.message);
}
return result;
};
this.then = function(task) {
try {
this._task.setNextTask(task);
this._task = task;
return this;
} catch(e) {
console.error("TaskQueue.then: " + e.message);
}
};
this.run = function() {
this._keepalive = true;
while(this._keepalive) {
var now = new Date().getTime();
this.next();
sleep(1);
}
};
this.stop = function() {
this._keepalive = false;
};
};
exports.createTaskQueue = function() {
return new TaskQueue();
};
exports.createTask = function(f, params) {
try {
return new Task(f, params);
} catch(e) {
console.error("createTask exception: " + e.message);
}
};
exports.putTask = function(q, f, params) {
try {
if (q instanceof TaskQueue) {
return q.put(new Task(f, params));
}
} catch(e) {
console.error("putTask exception: " + e.message);
}
};
exports.nextTask = function(q) {
try {
return q.next();
} catch(e) {
console.error("nextTask exception: " + e.message);
}
};
exports.run = function(q) {
q.run();
};
exports.stop = function(q) {
q.stop();
};
/*
exports.setTimeout = function() {
var f = null;
var delay = 0;
var params = [];
var args = arguments;
if (args.length > 2) {
f = arguments[0];
delay = args[1];
params = args.slice(2);
} else if (args.length == 2) {
f = args[0];
delay = args[1];
}
if (f != null) {
var when = new Date().getTime() + delay;
// ... todo ...
}
};
exports.setInterval = function() {
var f = null;
var delay = 0;
var params = [];
var args = arguments;
if (args.length > 2) {
f = args[0];
delay = args[1];
params = args.slice(2);
} else if (args.length == 2) {
f = args[0];
delay = args[1];
}
if (f != null) {
var when = new Date().getTime() + delay;
// ... todo ...
}
};
exports.Promise = function() {
// ... todo ...
};
*/
exports.VERSIONINFO = "Task Module (task.js) version 0.1";
exports.global = global;
exports.require = require;