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

JavaScript中如何将排序算法实现为generator函数 解决React排序可视化问题

React 冒泡排序可视化异常修复方案

问题根因

  • 生成器实例重复创建:原代码每次循环都会重新调用bSort生成新的生成器实例,每次仅能拿到第一次迭代的结果,因此数组仅会变更一次。
  • setState批量更新:同步for循环执行速度极快,React会自动合并多次setState操作,视图只会在循环全部结束后渲染一次最终结果。
  • 数组引用未变更:生成器内直接修改传入的原数组,数组引用地址不变,React可能会判定state无变化跳过渲染。
  • 无迭代间隔延迟:两次数组状态更新之间没有设置停顿时间,无法观察到排序的渐变过程。
  • 调用笔误:原组件方法内误调用了自身bubbleSorting而非引入的生成器bSort,会导致逻辑异常。

重构代码

1. 生成器函数优化

每次迭代返回新数组,不修改原数组,同时优化冒泡排序的循环边界:

export function *bSort (arr: number[]) {
    // 浅拷贝原数组,避免直接修改入参
    const sortArr = [...arr];
    const len = sortArr.length;
    for (let i = 0; i < len; i++) {
        // 末尾已排序的元素无需再次比较
        for (let j = 0; j < len - 1 - i; j++) {
            if (sortArr[j] > sortArr[j + 1]) {
                const tmp = sortArr[j];
                sortArr[j] = sortArr[j + 1];
                sortArr[j + 1] = tmp;
            }
            // 返回浅拷贝的新数组,变更引用触发state更新
            yield [...sortArr];
        }
    }
    return [...sortArr];
};

export default bSort;

2. 组件排序方法优化

使用async/await实现迭代延迟,生成器仅初始化一次,避免批量更新:
首先在组件内/外部定义延迟工具函数:

// 延迟函数,单位ms
const delay = (ms: number) => new Promise(resolve => setTimeout(resolve, ms));

修改组件的排序触发方法:

bubbleSorting = async () => {
    // 仅初始化一次生成器实例,传入初始待排序数组
    const sortGenerator = bSort(this.state.consequence);
    let stepResult = sortGenerator.next();
    while (!stepResult.done) {
        // 更新数组状态触发重渲染
        this.setState({ consequence: stepResult.value });
        // 停顿指定时间后再执行下一次迭代,可自行调整数值控制排序速度
        await delay(500);
        stepResult = sortGenerator.next();
    }
    // 最终状态更新
    this.setState({ consequence: stepResult.value });
};

额外优化建议

  • 可新增isSorting状态变量,排序过程中禁止重复触发排序操作,也可作为排序中断的开关。
  • 可将延迟时间做成可配置项,允许用户手动调整排序动画的速度。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.26 03:18:00