javascript - 如何使用 setTimeout 逐行执行 for 循环?
问题描述
我试图可视化一个冒泡排序算法,我试图找出一种方法让我的 for 循环每 1000 毫秒迭代一次,所以它会逐步执行,并且我能够绘制每次迭代的结果。
我尝试过使用 setTimeout,但是当 setTimeout 异步执行时,for 循环继续执行。还有另一种方法可以“逐步”通过 for 循环吗?
// bubble sort
function bubbleSort(arr) {
for (let i = 0; i < arr.length; i++) {
for (let j = 0; j < arr.length; j++) {
if (arr[j] > arr[j + 1]) {
let temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
delay();
}
}
}
return arr;
}
function delay() {
setTimeout(() => {
console.log('hello');
}, 1000);
}
解决方案
您可以将函数转换为生成器函数,并在每次排序后生成数组的状态。
如果你尝试调用.next().value
,当外循环结束时,会抛出异常。这是您可以捕获它并取消间隔的地方。
console.log('START');
let arr = [ 5, 3, 4, 2, 1 ],
gen = bubbleSort(arr),
wait = 1000,
counter = 0;
const intervalId = setInterval(() => {
try {
const value = gen.next().value.join(',');
console.log(`Step ${++counter}: ${value}`);
} catch (e) {
clearInterval(intervalId);
console.log('STOP');
}
}, wait);
function* bubbleSort(arr) {
for (let i = 0; i < arr.length; i++) {
for (let j = 0; j < arr.length; j++) {
if (arr[j] > arr[j + 1]) {
let temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
yield arr;
}
}
}
}
.as-console-wrapper { top: 0; max-height: 100% !important; }
或者,您可以尝试添加一个启动超时的回调,该超时将以线性方式返回。
let arr = [ 5, 3, 4, 2, 1 ], wait = 1000;
const stepFn = (step, arr) => {
const finalStep = Math.pow(arr.length, 2) - 1;
const result = arr.join(','); // Capture values
setTimeout(() => {
console.log(`Step ${step}: ${result}`); // Finally display them
if (step === finalStep) { console.log('STOP'); }
}, step * wait); // Asynchronous calls, but the timeout is linear
};
console.log('START');
bubbleSort(arr, stepFn);
function bubbleSort(arr, callback) {
for (let i = 0; i < arr.length; i++) {
for (let j = 0; j < arr.length; j++) {
if (arr[j] > arr[j + 1]) {
let temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
}
callback(i * arr.length + j, arr); // Insert a callback
}
}
}
.as-console-wrapper { top: 0; max-height: 100% !important; }
推荐阅读
- python - Bot 不响应命令,但他对事件做出反应
- javascript - aframe 360°图像手机屏幕手动垂直滚动问题(垂直触摸滚动)
- java - Spring Boot 自定义验证器不会返回到 Controller
- matlab - 在 Matlab 中从一个 txt 文件中导入多个矩阵
- alert - Splunk:如何设置通知通常行为的警报?
- python - 关于打印结果输出异常
- javascript - 当父级重新渲染时,React 子级会更新 DOM
- sed - 在特定行号之后使用 sed 模式附加
- c# - 无法登录 login.microsoftonline.com oauth 2 授权端点
- r - 如何使用 eventReactive 在按钮单击时读取和显示数据?