我有一个JavaScript函数,它在Microsoft Edge的画布上绘制。看起来有点像这样
function foo() {
drawSomething(canvas);
doACalculationThatTakesALongTime();
drawSomethingElse(canvas);
doACalculationThatTakesALongTime();
}
foo
作为事件处理程序附加到我的DOM中的某个事件。
我遇到的问题是,在doACalculationThatTakesALongTime
完成之前,foo
对画布的更新才会显示。这是预期的吗?相比之下,在Firefox中,更新立即出现。
答案 0 :(得分:1)
解耦解决方案:
var canvas = document.body.appendChild(document.createElement("canvas"));
var ctx = canvas.getContext("2d");
function drawSomething() {
ctx.fillStyle = "rgba(255,0,0,0.5)";
ctx.fillRect(0, 0, (canvas.width / 3) * 2, (canvas.height / 3) * 2);
}
function drawSomethingElse() {
var ctx = canvas.getContext("2d");
ctx.fillStyle = "rgba(0,0,255,0.5)";
ctx.fillRect(canvas.width / 3, canvas.height / 3, (canvas.width / 3) * 2, (canvas.height / 3) * 2);
}
function doACalculationThatTakesALongTime() {
var d = Date.now();
while (Date.now() - d < 2 * 1000) {}
console.log("Big calculation done");
}
function foo() {
ctx.clearRect(0, 0, canvas.width, canvas.height);
drawSomething();
setTimeout(doACalculationThatTakesALongTime, 1000);
drawSomethingElse();
setTimeout(doACalculationThatTakesALongTime, 1000);
}
setTimeout(foo, 1000);
&#13;
或者,如果执行顺序很重要,您可以将这些操作与Promises
链接在一起,同时使用requestAnimationFrame
确保帧渲染:
var canvas = document.body.appendChild(document.createElement("canvas"));
var ctx = canvas.getContext("2d");
var p = document.body.appendChild(document.createElement("p"));
function drawSomething() {
ctx.fillStyle = "rgba(255,0,0,0.5)";
ctx.fillRect(0, 0, (canvas.width / 3) * 2, (canvas.height / 3) * 2);
p.innerHTML += "Drawed something<br>";
}
function drawSomethingElse() {
var ctx = canvas.getContext("2d");
ctx.fillStyle = "rgba(0,0,255,0.5)";
ctx.fillRect(canvas.width / 3, canvas.height / 3, (canvas.width / 3) * 2, (canvas.height / 3) * 2);
p.innerHTML += "Drawed something else<br>";
}
function doACalculationThatTakesALongTime() {
var d = Date.now();
while (Date.now() - d < 2 * 1000) {}
p.innerHTML += "Big calculation done<br>";
}
function foo() {
ctx.clearRect(0, 0, canvas.width, canvas.height);
new Promise(function(resolve, reject) {
requestAnimationFrame(function() {
drawSomething();
resolve();
});
})
.then(function() {
return new Promise(function(resolve, reject) {
requestAnimationFrame(function() {
doACalculationThatTakesALongTime();
resolve();
});
});
})
.then(function() {
return new Promise(function(resolve, reject) {
requestAnimationFrame(function() {
drawSomethingElse();
resolve();
});
});
})
.then(function() {
return new Promise(function(resolve, reject) {
requestAnimationFrame(function() {
doACalculationThatTakesALongTime();
resolve();
});
});
})
}
foo();
&#13;