如何在JavaScript中从外部中断for循环的执行?

js中如何从外部中断for循环,起因是这段代码上层会反复进入这个for循环,每次进入的时候需要清除之前的执行效果,所以需要在循环外部来取消?大佬们知道如何做吗?

let progress = 0;
const listLength = 99999;
for (let i = 0; i < listLength; i++) {
    progress = (i+1) / listLength * 100;
    console.log('进度',progress);
}

之前尝试过,通过变量来中断,但是并没有达到实际效果。

let isBreak = false;
let progress = 0;
const listLength = 99999;
for (let i = 0; i < listLength; i++) {
    if (isBreak) break;
    progress = (i+1) / listLength * 100;
    console.log('进度',progress);
}

//尝试改变isBreak的值,延时队列会在for循环完成后才执行,顺序执行也是如此
//以上是内部中断,无法实现,考虑有没有外部中断的方式
阅读 2.3k
4 个回答

javascript单线程,你这个for循环也是同步的,
所以,当你已经开始for循环时,修改isBreak的值为true,
需要等for循环执行完成,才能将isBreak的值修改为true.


如果需要从外部中断,需要改成异步for循环,代码如下

const sleep = (time) => new Promise(resolve => setTimeout(resolve, time))
let globalBreak = false
async function startFor() {
    for (let i = 0; i <= 10; i++) {
        await sleep(1000)
        if (globalBreak) { break }
        console.log('i:' + i)
    }
}

startFor()
setTimeout(function() {
   globalBreak = true
}, 3000)

使用异步:

class AsyncState<T> {
    constructor(private state: T) {}
    get value(): Promise<T> {
        return Promise.resolve(this.state)
    }
    set value(newState: T) {
        this.state = newState
    }
}

const pState = new AsyncState(0)

async function printProgress(listLength = 99999) {
    const state = (await pState.value) + 1
    pState.value = state
    for (let i = 0; i < listLength; i++) {
        if (state < (await pState.value)) {
            console.log(`${state} 停止`)
            return
        }
        console.log('进度', ((i + 1) / listLength) * 100)
    }
}

printProgress(100)
queueMicrotask(() => printProgress(10))

输出:

进度 1
进度 2
进度 10
1 停止
进度 20
进度 30
...
进度 100

注意,需要在微任务(Promise)中调用 printProgress 才会取消上一次的调用。

你这代码没有给出任何break的条件, 等同于直接 process = 1;

我还尝试过一种笨方法,就是for循环内部每一个循环的内容执行过程都加到setTimeout中,把状态存下来,二次进入的时候统一循环clearTimeout销毁之前的;但是这种情况下无法收集progress进度。

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题
宣传栏