必须有一个简单的方法来做到这一点,但我是JS的新手。
我有一个javascript程序,(1)接受用户输入,(2)根据输入更新网页,然后(3)执行冗长的计算。问题是网页在长时间计算之后才会注册更新。有没有办法暂停执行,以便页面可以在长计算之前更新?
我尝试过setTimeout和window.setTimeout,但它们没有区别。
该程序用于玩游戏:用户输入移动,脚本更新位置,然后计算下一步。 postMessage使用div.innerHTML打印文本消息; buttonFn从用户获取输入,更新位置,打印消息,然后启动计算机计算。
function buttonFn(arg){
var hst = histButt;
hst.push(arg);
var nwmv = hst.clone();
postMessage("New move: " + nwmv.join());
if(status == opposite(comp) && !pauseQ){
var mvsposs = movesFromPos(posCur,status);
if(mvsposs.has(nwmv)){
updatePosCur(nwmv);
//waitasec();
if(comp == status && !pauseQ){
compTurn();
};
}
else{
histButt = nwmv;
};
};
};
答案 0 :(得分:4)
是的,请按此调用您的函数。使用setTimeout将允许在JS执行之前进行页面重排。
function buttonFn(arg){
var hst = histButt;
hst.push(arg);
var nwmv = hst.clone();
postMessage("New move: " + nwmv.join());
if(status == opposite(comp) && !pauseQ){
var mvsposs = movesFromPos(posCur,status);
if(mvsposs.has(nwmv)){
updatePosCur(nwmv);
//waitasec();
if(comp == status && !pauseQ){
setTimeout(function(){
compTurn();
},0);
};
}
else{
histButt = nwmv;
};
};
};
请记住,JS非常适合活动。如果你可以移开它,并在以后调用它们。这是我们支持多线程行为的唯一方式。
答案 1 :(得分:0)
答案 2 :(得分:0)
JavaScript是单线程的。如果你执行calc服务器端,你可以通过ajax获取结果,这是异步调用的,而不是阻止你的ui。
答案 3 :(得分:0)
如果您只需要支持现代浏览器(或者使用Transpiler),则现在可以使用ES6功能使此操作变得更加轻松,并且可以更加简化原始提问者试图使用的样式。 (我意识到这个问题已有8年历史了-在新的,最新的答案中没有什么害处!)
例如,您可以执行以下操作:
// helper function to use a setTimeout as a promise.
function allowUpdate() {
return new Promise((f) => {
setTimeout(f, 0);
});
}
// An infinitely looping operation that doesn't crash the browser.
async function neverStopUpdating(someElement) {
let i = 0;
while (true) {
someElement.innerText = i;
i++;
await allowUpdate();
}
}
如果您要进行硬计算,则要确保不要太频繁地等待此操作-在本示例中,在撰写本文时,在Chrome中,i
仅每增加约150第二个原因是setTimeout的上下文切换不快(如果不屈服于更新,则每秒将获得成千上万个)。您可能想要找到一个平衡点,或者在允许更新之前总是执行一些迭代,或者例如。自上次允许更新以来经过100毫秒后,请在循环中调用Date.now()并产生更新。