我正在构建一个排序算法可视化程序,它是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;
};
答案 0 :(得分:0)
获取循环和异步权很复杂。但是我们有一个正确的工具: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);
}
})();