首先,重要的是要提到 JavaScript 是完全单线程的。模拟多线程真的不是要走的路。依赖事件循环会好得多。
如前所述,可以使用网络工作者,但它们并没有真正的跨浏览器合规性,所以我将忽略网络工作者。此外,您不能对 Web Worker 进行任何 DOM 操作。
我想说看看node.js 来推理为什么事件循环是多线程的一个很好的替代方案。我相信他在video 中很好地解释了为什么它是一个不错的选择。
因此,与其拥有一组函数并对其进行迭代,不如创建一个事件并将一组函数绑定到它们并触发所述事件。在backbone.js 中可以找到一个非常轻量级的事件实现。
您不能只暂停 JavaScript 中的一个线程,因为只有一个。如果函数中没有点,就无法暂停或恢复函数。
只有一种方法可以模拟这一点。编写一个 JavaScript 解析器,将您精心构建的 JavaScript 拆分开来,并构建一个允许您暂停和恢复 JavaScript 的系统。
以这个函数为例
function(i) {
j = i + 1;
console.log(j);
return foo(j);
}
并将其转换成这个
var bar = function(i) {
var r = {};
var j = i + 1;
var f = function() {
console.log(j);
var g = function() {
return foo(j);
};
onNext(g, arguments.callee, this, r);
};
onNext(f, arguments.callee, this);
return r;
}
您需要使用.suspend 和.resume 扩展函数
Function.prototype.suspend = function() {
this.__suspended = true;
}
Function.prototype.resume = function() {
this.__suspended = false;
}
function onNext(callback, function, context, returnObj) {
if (!function.__suspended) {
var cb = function() {
Backbone.Events.unbind("run", cb);
returnObj.r = callback.call(this);
}
Backbone.Events.bind("run", cb);
}
}
setInterval(function() {
Backbone.Events.trigger("run");
}, 5);
您还必须将所有对var a = b() 的引用替换为
callFunctionAsync(b, context, args, function(return) {
var a = return;
...
});
我将把实施留给你。目前所有函数都返回一个对象r,并且只有当r.r 设置为一个值时,它才会“返回”。因此,只需检查事件循环是否已“返回”,方法是检查是否设置了 r.r 以及是否触发了函数异步回调。
嘿,看看我们有什么。通过在事件循环中运行线程来模拟线程。最好在代码中本地使用事件循环,而不是通过它模拟线程。
当你再次循环事件循环时,基本上让你的函数运行下一行代码。并检查在您绕过事件循环时特定的“功能”是否被暂停或恢复。
为了简洁起见,我没有实现将函数的返回冒泡返回到“函数”。这应该不难模仿。
要么直接使用事件循环,要么使用假线程方法并让编译器编译你的代码,这样你编码时它就不会看起来很可怕。
如果你造成死锁,祝你好运。