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

使用Promise .then时未等待响应完成就执行后续请求的问题

问题原因与解决方案

核心问题

你遇到的问题是React的状态更新是异步的:调用setOrderid(response.data.id)后,orderid并不会立刻变成新值,后续then里访问的还是旧的状态值,导致第二个POST请求用错了订单ID。

修复方案

直接使用接口响应里的订单ID,不依赖React状态的异步更新,同时用Promise.all批量处理关联请求,确保流程正确。

方案一:优化链式Promise写法

const orderHandler = () => {
  setError('')

  token
    ? axios
        .post(
          'http://localhost:8000/order/',
          {
            notes: notes,
            price: quantPrice,
            city: city,
            street: street,
            zipcode: zipcode,
          },
          {
            headers: {
              Authorization: 'Token ' + token,
            },
          },
        )
        .then((response) => {
          const newOrderId = response.data.id;
          console.log(newOrderId, 'wielki chuj');
          setOrderid(newOrderId); // 状态更新留给其他场景用,当前请求直接用newOrderId

          // 批量提交订单-商品关联请求
          return Promise.all(
            cartItems.map((j) =>
              axios.post(
                'http://localhost:8000/orderproduct/',
                {
                  order: newOrderId,
                  product: j.id,
                  quantity: j.quant,
                },
                {
                  headers: {
                    Authorization: 'Token ' + token,
                  },
                },
              )
            )
          );
        })
        .catch((error) => {
          console.log(error.response?.data?.body);
          setError(error.response?.data?.body || '未知错误');
        })
    : setError('You must be logged in')
}

方案二:用async/await让流程更直观

const orderHandler = async () => {
  setError('');
  if (!token) {
    setError('You must be logged in');
    return;
  }

  try {
    // 第一步:创建订单
    const orderRes = await axios.post(
      'http://localhost:8000/order/',
      { notes, price: quantPrice, city, street, zipcode },
      { headers: { Authorization: 'Token ' + token } }
    );
    const newOrderId = orderRes.data.id;
    setOrderid(newOrderId);
    console.log(newOrderId);

    // 第二步:批量创建订单-商品关联
    await Promise.all(
      cartItems.map(item => 
        axios.post(
          'http://localhost:8000/orderproduct/',
          { order: newOrderId, product: item.id, quantity: item.quant },
          { headers: { Authorization: 'Token ' + token } }
        )
      )
    );
  } catch (err) {
    console.log(err.response?.data?.body);
    setError(err.response?.data?.body || '未知错误');
  }
};

关键说明

  1. 避免依赖异步状态更新:setOrderid是异步操作,调用后不能立刻拿到新值,直接用接口返回的response.data.id是最可靠的方式。
  2. 用Promise.all批量处理:多个订单-商品关联请求可以同时发起,Promise.all会等待所有请求完成,也方便统一捕获错误。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.12 19:11:30