我在Worker上运行一个非常昂贵的任务,类似于
for(var i = 0; i < 1000000000; i++)
//operations using i...
我怎样才能这样做,在那个循环中,我可以检查是否收到了工作者所有者要求它停止的消息?我想有这样的东西
for(var i = 0; i < 1000000000; i++)
if(windowDidNotAskToStop())
//operations using i...
现在我已经注册了一个onmessage函数,所以我可以开始收听来自所有者的消息,但是在我的循环运行时它被阻止(显然)。
我认为来自所有者的postMessage调用在某处排队,所以我只需访问它就可以处理来自循环内部的调用。
答案 0 :(得分:2)
您必须像往常一样处理事件并设置标记,但请务必留出时间让您的循环接收事件,可能使用setTimeout
:
var exitLoop = false;
(function loop(i) {
if (exitLoop || i >= 1000000000) {
return;
}
// …
setTimeout(function () {
loop(i + 1);
}, 0);
})(0);
onmessage = function (e) {
if (e.data === 'stop') {
exitLoop = true;
}
};
或者,作为一般效用函数:
function asyncIterateRange(start, end, callback) {
var exitLoop = false;
var doneCallbacks = [];
(function loop(i) {
if (exitLoop) {
return;
}
if (i >= end) {
doneCallbacks.forEach(function (callback) {
callback();
});
return;
}
callback(function () {
setTimeout(function () {
loop(i + 1);
}, 0);
});
})(start);
return {
abort: function abort() {
exitLoop = true;
},
done: function addDoneCallback(callback) {
doneCallbacks.push(callback);
}
};
}
像这样使用它:
var innerIterator;
var outerIterator = asyncIterateRange(0, 1000000, function outerLoop(next) {
innerIterator = asyncIterateRange(0, 1000, function innerLoop(next) {
// …
next();
}).done(next);
});
// To stop:
if (innerIterator) {
innerIterator.abort();
}
outerIterator.abort();