欢迎光临
我们一直在努力

从零开发 AI Chatbot:Loading State 加载状态管理

从零开发 AI Chatbot:Loading State 加载状态管理

一、前言

在之前的开发中,我们已经学习了消息渲染、Markdown 渲染、代码高亮、自动滚动等前端知识。

随着 KK Chat 的功能不断完善,聊天界面的交互体验也变得越来越重要。

在使用 AI Chatbot 时,我们经常会看到这样的过程:

  • 用户发送消息。
  • 界面显示正在处理。
  • AI 开始生成回复。
  • 回复完成,界面恢复正常。
  • 这里涉及一个重要的前端概念:Loading State(加载状态)。

    如果没有合理的加载状态管理,用户发送消息后可能不知道请求是否成功,也可能连续点击发送按钮,导致重复请求。

    因此,今天我们来学习 Loading State 的基本原理,以及如何将它应用到 KK Chat 中。

    二、什么是 Loading State?

    Loading State 是指程序在执行异步操作期间,用来表示当前处理状态的一种机制。

    在 AI Chatbot 中,一次请求通常需要经过以下流程:

    用户发送消息
    |
    v
    开始请求 AI
    |
    v
    显示加载状态
    |
    v
    接收 AI 回复
    |
    v
    渲染回复内容
    |
    v
    结束加载状态

    加载状态不仅可以用来显示动画,还可以控制发送按钮、输入框等交互元素。

    例如:

    • 请求进行中:显示“正在生成回复”。
    • 请求成功:显示 AI 的回复。
    • 请求失败:显示错误提示。
    • 请求结束:允许用户继续发送消息。

    因此,Loading State 不只是一个视觉效果,更是前端管理异步请求的重要手段。

    三、使用 isLoading 管理状态

    在 JavaScript 中,我们可以使用一个布尔变量表示请求是否正在进行。

    let isLoading = false;

    其中:

    • false:当前没有正在执行的请求。
    • true:当前正在处理请求。

    当用户发送消息时,将状态设置为 true;请求结束后,再恢复为 false。

    例如:

    async function sendMessage() {
    isLoading = true;

    try {
    // 在这里执行异步请求
    } finally {
    isLoading = false;
    }
    }

    这里使用了 try…finally。

    try 用于执行主要操作,finally 中的代码则会在流程离开 try 后执行,包括发生异常的情况。

    这样可以避免请求失败后,加载状态一直停留在进行中。

    需要注意:上面只是状态管理的基础示例。实际项目还需要根据 isLoading 的变化更新页面。

    四、如何将加载状态显示在页面上?

    假设聊天界面有一个发送按钮和一个状态提示区域:

    <button id="send-btn">发送</button>

    <div id="loading-status"></div>

    我们可以通过 JavaScript 更新它们的状态:

    const sendBtn = document.getElementById("send-btn");
    const loadingStatus = document.getElementById("loading-status");

    function setLoading(loading) {
    sendBtn.disabled = loading;

    loadingStatus.textContent = loading
    ? "AI 正在生成回复…"
    : "";
    }

    当调用:

    setLoading(true);

    页面会显示加载提示,并禁用发送按钮。

    当调用:

    setLoading(false);

    加载提示消失,发送按钮恢复可用。

    这种方式可以将状态管理集中在一个函数中,避免在多个地方重复编写相同的界面更新逻辑。

    五、在异步请求中使用 Loading State

    接下来,将加载状态与异步请求结合起来。

    下面是一个简化的示例:

    async function sendMessage() {
    if (isLoading) {
    return;
    }

    isLoading = true;
    setLoading(true);

    try {
    const response = await fetch("/api/chat", {
    method: "POST",
    headers: {
    "Content-Type": "application/json"
    },
    body: JSON.stringify({
    message: "你好"
    })
    });

    if (!response.ok) {
    throw new Error(`HTTP ${response.status}`);
    }

    const data = await response.json();

    console.log(data);
    } catch (error) {
    console.error("请求失败:", error);
    loadingStatus.textContent = "请求失败,请稍后重试。";
    } finally {
    isLoading = false;
    sendBtn.disabled = false;
    }
    }

    这个示例展示了完整的异步请求流程:

  • 检查当前是否正在请求,避免重复提交。
  • 开启加载状态。
  • 使用 fetch() 发送 HTTP 请求。
  • 检查 HTTP 响应状态。
  • 处理返回的数据。
  • 捕获异常。
  • 在请求结束后恢复界面状态。
  • 需要注意,示例中的 /api/chat、请求参数和响应格式需要根据实际后端接口进行调整。

    此外,HTTP 请求返回 4xx 或 5xx 状态码时,fetch() 通常不会自动抛出异常,因此需要通过 response.ok 主动检查。

    六、Loading State 与 Streaming 的关系

    在 KK Chat 中,我们还需要考虑 Streaming(流式输出)。

    普通请求与 Streaming 的处理流程有所不同。

    1. 普通请求

    发送消息
    |
    v
    等待响应
    |
    v
    获取完整回复
    |
    v
    显示回复
    |
    v
    结束加载

    2. Streaming 请求

    发送消息
    |
    v
    开始接收数据
    |
    v
    持续读取数据片段
    |
    v
    逐步更新 AI 回复
    |
    v
    数据流结束
    |
    v
    结束加载

    对于 Streaming,不能在收到第一个数据片段时就认为整个请求已经结束。

    正确的做法是:

    在数据流正常结束,或者请求发生错误并完成必要的清理后,再结束本次加载状态。

    这样才能保证加载提示、发送按钮和 AI 回复的显示状态保持一致。

    七、实践中可能遇到的问题

    1. 请求失败后,发送按钮一直处于禁用状态

    原因:

    程序只在请求成功时恢复按钮,没有处理异常情况。

    解决方案:

    使用 finally 统一恢复状态,避免成功和失败的分支各自维护一套清理逻辑。

    2. 用户连续点击发送,产生重复请求

    原因:

    请求进行期间,程序仍然允许用户重复提交。

    解决方案:

    发送请求前检查 isLoading,并在请求开始时禁用发送按钮。

    需要注意,前端限制主要用于改善交互体验,并不能代替后端必要的请求校验。

    3. Streaming 已经开始输出,但加载状态提前结束

    原因:

    程序将“收到第一段数据”误认为“整个请求已经结束”。

    解决方案:

    将加载状态的生命周期与完整的数据流处理过程绑定,在读取完成或发生异常后再进行清理。

    4. 加载动画一直显示

    原因:

    某些代码路径没有恢复状态,或者数据流异常后没有执行清理逻辑。

    解决方案:

    梳理请求的完整生命周期,检查成功、失败和中断等路径是否都能正确结束加载状态。

    八、今天的收获

    通过今天的学习,我进一步理解了前端状态管理与异步请求之间的关系。

    主要知识点包括:

    • Loading State 的概念与作用。
    • 使用布尔变量表示请求状态。
    • 使用 try…catch…finally 处理异步操作。
    • 使用 disabled 控制发送按钮。
    • 通过 response.ok 检查 HTTP 响应状态。
    • 理解 Streaming 场景下加载状态的生命周期。

    其中最重要的一点是:

    加载状态必须与实际请求的生命周期保持一致。

    它不是简单地显示一个动画,而是决定界面在请求开始、处理中、成功和失败时应该如何响应。

    对于 KK Chat 来说,合理的加载状态管理能够减少重复提交,改善用户反馈,也为后续实现停止生成、请求取消等功能打下基础。


    KJ

    项目:KK Chat

    系列:《从零开发 AI Chatbot》

    赞(0)
    未经允许不得转载:171主机测评 » 从零开发 AI Chatbot:Loading State 加载状态管理
    分享到: 更多 (0)

    评论 抢沙发

    • 昵称 (必填)
    • 邮箱 (必填)
    • 网址