Microsoft Edge 何时进行 canvas 更新?

When are canvas updates made in Microsoft Edge?

我有一个 JavaScript 函数,它利用了 Microsoft Edge 中的 canvas。有点像这样

function foo() {
    drawSomething(canvas);
    doACalculationThatTakesALongTime();
    drawSomethingElse(canvas);
    doACalculationThatTakesALongTime();
}

foo 作为事件处理程序附加到我的 DOM.

中的某个事件

我遇到的问题是 doACalculationThatTakesALongTime 对 canvas 所做的更新在 foo 完成之前不会出现。这是可以预料的吗?相比之下,在 Firefox 中更新会立即出现。

解耦方案:

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);

或者,如果执行顺序很重要,您可以将这些操作与 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();