在 javascript 中 wait/sleep 的更好方法

A better way to wait/sleep in javascript

我正在用 JS 构建一个脚本,它将 运行 在网页上按顺序修改元素。我需要能够 wait/sleep 同时将整个过程包含在 运行ning 函数中。下面的例子是不言自明的,也是我需要帮助的一个非常简单但全面的例子:

<body>
  <button id="button-start" onclick="updateStatus('started')">START!</button>
  <button id="button-1" onclick="console.log('step_1')">button-1</button>
  <button id="button-2" onclick="console.log('step_2')">button-2</button>

  <script>
  var status = 'stopped';
  var step = 'initial';

  function updateStatus(newStatus) {
    status = newStatus;
    script();
  }

  function wait(msec) {
    var now = new Date().getTime();
    while(new Date().getTime() < now + msec){ /* do nothing */ }
  }

  function script() {
    while (status == 'started') {
      if (step == 'initial') {
        console.log('Script started');
        step = 'click_button1';
      }

      if (step == 'click_button1') {
        document.getElementById("button-1").click();
        wait(1000)
        step = 'click_button2';
      }

      if (step == 'click_button2') {
        document.getElementById("button-2").click();
        step = 'done';
      }

      if (step == 'done') {
        status = 'stopped';
      }

    }
    console.log('Script done');
  }

  </script>    
</body>

这完全符合我的需要,但显然使用 while 循环不是一个好主意。我见过很多其他类似的问题,但我不明白如何调整其他答案来解决我需要帮助的问题:

  1. 一个中心 function/loop 作用于不同的 'steps' 并且在这些步骤中有多个不同的 waits/sleeps
  2. 需要避免使用乱序执行的东西

为了使它看起来不错,您可以使用 async and a Promise,它在 setTimeout 之后解析。

注意行

await wait(1000)

<body>
  <button id="button-start" onclick="updateStatus('started')">START!</button>
  <button id="button-1" onclick="console.log('step_1')">button-1</button>
  <button id="button-2" onclick="console.log('step_2')">button-2</button>

  <script>
  var status = 'stopped';
  var step = 'initial';

  function updateStatus(newStatus) {
    status = newStatus;
    script();
  }

  function wait(msec) {
    return new Promise(res => {setTimeout(()=>{res()}, msec)})
  }

  async function script() {
    while (status == 'started') {
      if (step == 'initial') {
        console.log('Script started');
        step = 'click_button1';
      }

      if (step == 'click_button1') {
        document.getElementById("button-1").click();
        await wait(1000)
        step = 'click_button2';
      }

      if (step == 'click_button2') {
        document.getElementById("button-2").click();
        step = 'done';
      }

      if (step == 'done') {
        status = 'stopped';
      }

    }
    console.log('Script done');
  }

  </script>    
</body>