DOM 的更新在 CPU 密集 WASM 调用期间不可见

Updates to DOM not visible during CPU intensive WASM call

有一个 WASM 程序,在我的机器上 运行 大约需要 12 秒。为了让用户留在网站上,最好表明该程序正在取得进展。我在 C++ WASM 代码中插入了一些使用 EM_ASM_(...) 的调用到等同于:

的 JS 函数
function updateStatus(number) {
  console.log("status: ", number);
  document.getElementById("status").innerHTML = "Status: " + number;
}

虽然控制台获得实时更新,但“状态”DOM 元素在 WASM 代码完成之前不会更新。

我尝试在 C++ 代码中的 updateStatus() 调用之后添加 sleep(1),但这并没有导致更新。

JavaScript 运行 时间让给了 WebAssembly,这就解释了为什么 UI 没有更新。为实现您的目标,您需要 运行 Web Worker 中的代码。

以下 C 代码似乎可以工作,但下面提到了一个单独的问题:

EM_JS(void, updateStatus, (int number), {
  Asyncify.handleAsync(async() => {
    await Promise.resolve()
    .then(function() {
      console.log("status: ", number);
      document.getElementById("status").innerHTML = "Status: " + number;
    });

    await new Promise(r => setTimeout(r, 50));
  });
});

void myWASM() {
  ...
  for(int number = 0; number < MAX; number++) {
    ...
    updateStatus(number);
    ...
  }
  ...
  printf("done with myWASM()");
}

如果最后没有 Promise/setTimeout 调用,更新不会出现,但这可能是 DOM 更新的一般特征?

奇怪的是 cwrapmyWASM() returns 到 JS 调用者 before “用 myWASM() 完成”执行。似乎 myWASM() 调用现在是异步的?转到 post 一个关于此的单独问题。

感谢@sbc100 建议 ASYNCIFY。