在Python中,有一个名为gevent的库可以实现协作式多任务处理。有时,让两个长时间运行的函数相互执行会很有用。例如:
def long_running_func1():
while True:
# processor intensive
gevent.sleep()
gevent.sleep调用将任务置于睡眠状态。没有参数,它只会让执行到其他任务。
在浏览器中使用Javascript,我发现自己想要类似的东西,以便在处理器密集型工作之间,UI有机会更新。类似的东西:
var data = [];
setTimeout(function () {
while (true) {
// Update UI with data.slice(data.length - 5, 5)
// gevent.sleep(0);
}
}, 0);
setTimeout(function () {
while (true) {
// var value = computation;
// data.append(value);
// gevent.sleep(0);
}
}, 0);
Javascript是否提供某种允许这种模式的多任务处理?
我一直在使用的模式是将上面的内容重写为:
var data = [];
function update_ui() {
// Update UI with data.slice(data.length - 5, 5)
}
function repeatedly() {
var value = computation;
data.append();
update_ui();
setTimeout(repeatedly, 0);
}
repeatedly();
但随着代码变得越来越复杂,这种模式不可避免地涉及到更多与setTimeout链接的函数,而且它的可读性不高。
有比上面更好的模式吗?
答案 0 :(得分:2)
Javascript是由大自然驱动的事件,但你总是在单个线程上工作。
IO是唯一始终处理异常的东西(浏览器javascript中没有阻塞IO功能)。
以块为单位拆分长计算,如果要进行长计算,请使用异步库为代码提供结构,并避免锁定UI。
https://github.com/caolan/async
类似的东西:
var LongTask = function() {
this.state = 0;
this.result = 'whatever';
};
LongTask.prototype.start = function(callback) {
async.whilst(
this._isFinished.bind(this),
this._doChunk.bind(this),
function(error) {
callback(error, this.result);
}
);
};
LongTask.prototype._isFinished = function() {
return this.state > 1000;
};
LongTask.prototype._doChunk = function(callback) {
var chunkEnd = this.state + 10;
while (this.state++ < chunkEnd) {
.... do something ...
}
// In NodeJS, you would call process.nextTick(callback)
setTimeout(callback, 0);
};
以后或其他文件
var task = new Task();
task.start(function(error, result) {
// work is done without locking the whole process
});