You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何终止JavaScript中使用sleep函数实现的循环?

实现可终止的循环输出功能

当前代码的问题在于:用for循环一次性创建了所有的sleep Promise,这些任务会被浏览器按计划依次执行,就算点击Stop也无法中断;重复点击Submit还会叠加多个循环,导致输出混乱。要实现中途停止和重新执行,可按以下方案修改:

核心思路

  • 用全局终止标志控制循环是否继续
  • 把同步for循环改成异步循环(async/await),让每次迭代都能检查终止状态
  • 点击Submit时先终止当前运行的循环,再启动新循环

修改后的完整代码

JavaScript 部分

let submitBtn,
    stopBtn,
    firstStepInput,
    lastStepInput,
    output = 0,
    stopOutput = 0;
// 新增终止标志和当前循环的Promise引用
let isStopped = false;
let currentLoop = null;

document.addEventListener("DOMContentLoaded", () => {
    submitBtn = document.querySelector('#submit');
    stopBtn = document.querySelector('#stop');
    firstStepInput = document.querySelector('#firstStep');
    lastStepInput = document.querySelector('#lastStep');
    output = document.querySelector('#output');
    stopOutput = document.querySelector('#stopOutput');

    submitBtn.addEventListener('click', getValueInputs);
    stopBtn.addEventListener('click', stopLoop);
})

function sleep(ms) {
    return new Promise(resolve => setTimeout(resolve, ms));
}

// 改成async函数,用异步循环替代同步for
const getValueInputs = async () => {
    // 先终止当前正在运行的循环
    if (currentLoop) {
        isStopped = true;
        await currentLoop; // 等待当前循环完全停止
    }

    // 重置状态
    isStopped = false;
    let firstInputValue = +firstStepInput.value || 0;
    let lastInputValue = +lastStepInput.value || 100;
    let current = firstInputValue;

    // 用while循环实现异步迭代,每次都检查终止标志
    currentLoop = (async () => {
        while (current <= lastInputValue && !isStopped) {
            output.innerHTML = current;
            await sleep(1000); // 原代码i*1000会导致间隔越来越长,这里改成固定1秒,可按需调整
            current++;
        }
        // 循环结束后重置引用
        currentLoop = null;
    })();
}

const stopLoop = () => {
    isStopped = true;
    stopOutput.innerHTML = output.innerHTML;
}

HTML 部分

<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min.css" rel="stylesheet"/>
<div>
    <div class="ms-3">
        <div class="d-flex align-items-center mt-3">
            <div>
                <label for="firstStep">firstStep</label>
                <input id="firstStep" type="number" class="form-control" />
            </div>
            <span class="mx-3">to</span>
            <div>
                <label for="lastStep">lastStep</label>
                <input id="lastStep" type="number" class="form-control" />
            </div>
        </div>
        <div class="mt-3 mx-auto">
            <button id="submit" class="btn btn-sm btn-primary">Submit</button>
            <button id="stop" class="btn btn-sm btn-info">Stop</button>
        </div>
        <div class="mt-3">
            <p id="output"></p>
        </div>
        <div class="mt-3">
            <p id="stopOutput"></p>
        </div>
    </div>
</div>

关键修改说明

  1. 终止标志isStopped:每次循环迭代前都会检查这个标志,一旦设为true就立即退出循环
  2. 异步循环:用async/await配合while循环,替代原来的同步for循环,确保每次延迟后都能响应终止指令
  3. 循环跟踪:用currentLoop记录当前正在运行的循环Promise,点击新的Submit时先终止旧循环,避免多个循环同时运行
  4. Stop功能优化:点击Stop时不仅记录当前值,还会终止循环,停止后续输出

内容的提问来源于stack exchange,提问作者davood beheshti

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.29 00:54:56