javascript - 在等待时执行延迟函数所依赖的代码

标签 javascript settimeout

在下面的最小示例中,旧内容的替换通过 setTimeout 延迟,以便让用户有时间完成查看。与此同时,正在准备新内容,以避免在执行可能代价高昂的任务时阻塞用户界面。

var div = document.getElementById('wrapper');
var newContent = document.createElement('ul');

setTimeout(function() {
  var header = div.firstElementChild;
  header.innerHTML = 'New Content';
  header.nextElementSibling.remove();
  div.appendChild(newContent);
}, 2000);

// Make new content while we wait
[1, 10, 100, 1000].forEach(function(x) {
  var li = document.createElement('li');
  li.innerHTML = 'Factorial of ' + x + ' is ' + factorial(x);
  newContent.appendChild(li);
});

function factorial(num) {
  if (num === 0) {
    return 1;
  } else {
    return (num * factorial(num - 1));
  }
}
<div id='wrapper'>
  <h1>Old content</h1>
  <p>Read it before it's gone.</p>
</div>

我对这种方法的担忧是,它似乎无法处理 newContent 在替换即将发生时未准备就绪的情况。我也不确定这种方法是否会阻塞用户界面,或者 setTimeout 使用的任务是否会同时执行。

如何确保用户界面在执行可能代价高昂的任务时不会被阻塞并在完成后立即使用它?

最佳答案

长时间运行的计算会阻塞浏览器,这绝不是一个好主意。因此,你应该把它放在网络 worker 中。

如今,使用 promises 等异步工具编写异步代码是更好的做法。这是一种通用的伪代码级方法:

// Create a promise which fulfills after some # of ms.
function timeout(ms) {
  return new Promise(resolve => setTimeout(resolve, ms));
}

// Create the worker, kick it off, and 
// return a promise which fulfills when the worker reports a result.
function waitWorker() {
  const worker = new Worker('factorial.js');
  worker.postMessage([1, 10, 100, 1000]);

  return new Promise(resolve => 
    worker.addEventListener('message', event => resolve(event.data))
  );
}

// Wait for both the worker to complete and the two seconds to elapse.
// Then output the data.
Promise.all([timeout(2000), waitWorker()])
  .then(values => output(values[1]);

编写 worker 留作练习。

使用异步函数

如果您的环境支持,您还可以使用异步函数更清楚地表达这一点,如下所示:

async function calcAndWait() {
  const result = waitWorker(); // Kick off computation.
  await timeout(ms);           // Wait for two seconds.
  output(await result);        // Wait for computation to finish and output.
}

关于javascript - 在等待时执行延迟函数所依赖的代码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39666416/

相关文章:

JavaScript 和 HTML 表单 : Which button is the submitter?

javascript - 使用 `this` 中的成员函数时,将 babel 类保留为 `setTimeout`

javascript - setTimeout(fun) 有一个参数? (未指定超时)

javascript - setTimeout 循环等待另一个 setTimeout 循环

javascript - 如何让函数等到对象的值不是未定义的 js setTimeout

javascript - 设置 href 属性替换链接的文本

javascript - 使用 JavaScript 从外部图像获取颜色

javascript - 如何将更多条件附加到 if 语句?

javascript - 获取所有匹配元素的数据属性?

javascript - jquery 淡出,淡入,等待,淡入再次损坏