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

React.JS中API调用使用stale陈旧值问题如何解决

问题根因

该问题是典型的Promise异步时序错误,和并行逻辑无关。JavaScript为单线程事件循环模型,findBook(title)返回的Promise属于异步任务,传入.then()的回调会被暂存到微任务队列,不会阻塞后续同步代码执行。
现有代码的实际执行顺序:

  1. 初始化变量bookId,赋值为-1
  2. 调用findBook发起书籍查询请求,将「给bookId赋值、打印bookId」的回调注册到微任务队列,代码直接向下执行,不会等待查询请求返回
  3. 同步拼接DELETE请求的API地址,此时bookId仍为初始值-1
  4. 基于拼接好的、携带-1的地址发起DELETE请求
  5. 所有同步代码执行完毕后,事件循环才会处理微任务队列中的回调,此时才会将bookId更新为查询到的4,但删除请求早已发出,无法拿到更新后的值。
    你控制台中打印出4的时机晚于DELETE请求报错的时机,也能印证这个执行顺序。
修复方案

将所有依赖findBook返回结果的逻辑全部移入Promise链式调用中,确保拿到正确的bookId后再拼接地址、发起删除请求:

export function deleteBook(title: string): Promise<Book> {
    return findBook(title)
        .then((response) => {
            const bookId = Number(response[0].id);
            const API = `${apiURL}/api/books/${bookId}`;
            return axiosInstance.delete(API);
        })
        .then((responseJson) => responseJson.data);
}

如果使用async/await语法,逻辑会更直观,从根源上避免时序错乱问题:

export async function deleteBook(title: string): Promise<Book> {
    const response = await findBook(title);
    const bookId = Number(response[0].id);
    const API = `${apiURL}/api/books/${bookId}`;
    const responseJson = await axiosInstance.delete(API);
    return responseJson.data;
}
优化提示
  • 无需额外使用Promise.resolve/Promise.reject包装返回值,axios调用本身就返回Promise,直接返回链式调用结果即可,冗余包装会增加不必要的代码量
  • 做接口调用时建议增加异常捕获逻辑,比如查询不到对应书籍、删除权限不足等场景的错误提示

运行结果截图

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.30 18:39:55