【问题标题】:JavaScript setTimeout Order Of ExecutionJavaScript setTimeout 执行顺序
【发布时间】:2019-12-04 04:07:33
【问题描述】:

我正在构建一个排序算法可视化工具,这是 https://www.cs.usfca.edu/~galles/visualization/ComparisonSort.html 的简化版本。如果没有 setTimeout 函数,数组会按预期自行排序,并且条形图的顺序正确。但是我想让它像那个例子一样动画,但是在添加 setTimeout 函数之后,我得到了我想要的效果,但是它发生了乱序并且排序错误。我知道超时函数是在主线程之后执行的,但我不明白为什么这是一个问题,例如。间隔为 0 不应该仍然正确地对数组进行排序吗?据我了解,setTimeout 函数都将按相同的顺序运行。

我尝试为两个 setTimeOuts 使用不同的间隔,但即使在 0 时,事情也会发生乱序并且数组排序不正确。对于上下文,所有 updateSlowPointer 和 updateFastPointer 所做的都是突出显示我们正在查看的第 j 个和 j + 1 个条。交换,交换两个条,只需交换 CSS 类。

let bubbleSort = (inputArr) => {
let len = inputArr.length;
for (let i = 0; i < len; i++) {
    for (let j = 0; j < len; j++) {
        setTimeout(() => {
            updateSlowPointer(inputArr[j], inputArr[j - 1]);
            updateFastPointer(inputArr[j + 1]);
        }, 0); 

        if (inputArr[j] > inputArr[j + 1]) {
            setTimeout(() => {
                swap(inputArr[j], inputArr[j + 1]);
            }, 0);

            let tmp = inputArr[j];
            inputArr[j] = inputArr[j + 1];
            inputArr[j + 1] = tmp;
        }
    }
}
    return inputArr;
};

【问题讨论】:

  • 但是您的ifs 检查当前状态,而您的突变异步发生

标签: javascript asynchronous


【解决方案1】:

正确处理循环和异步是很复杂的。但是我们有一个工具可以做到这一点:async 函数!然后您可以轻松地await 循环。或者,如果您希望能够逐步运行算法,我认为这是您想要的,生成器函数可能是您选择的工具:

  function* bubbleSort(inputArr) {
    let len = inputArr.length;
    for (let i = 0; i < len; i++) {
      for (let j = 0; j < len; j++) {
        updateSlowPointer(inputArr[j], inputArr[j - 1]);
        updateFastPointer(inputArr[j + 1]);
      }

      if (inputArr[j] > inputArr[j + 1]) {
        swap(inputArr[j], inputArr[j + 1]);
      }

      let tmp = inputArr[j];
      inputArr[j] = inputArr[j + 1];
      inputArr[j + 1] = tmp;

       yield inputArr; // < let other code step in here
   }
   return inputArr;
 }

然后您可以使用async function 逐步执行生成器:

 const timer = ms => new Promise(res => setTimeout(res, ms));

 (async function() {
     let stepper = bubbleSort([1, 3, 2]), done = false;
     while(!done) {
       ({ done, value }) = stepper.next();
       // visualization here
       console.log(value);
       await timer(1000);
     }
  })();

【讨论】:

    猜你喜欢
    • 2011-06-19
    • 1970-01-01
    • 2012-11-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多