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

React Query多mutateAsync执行顺序问题:如何串行执行后跳转

如何让两个mutateAsync串行执行并在都成功后跳转页面

问题场景

需求:依次执行两个mutateAsync,仅当两者都执行成功后跳转到指定页面。当前使用的代码如下:

const changeStatus = useChangeConsultStatus();
const editConsult = useEditConsulta();

async function onClickAttended() {
    
    await editConsult.mutateAsync({ consultID: consultID, consult: consultValues });
    await changeStatus.mutateAsync({ consultID: consultID, status: "PENDING" });

    console.log("Edit consult status:", editConsult.status ) //Edit consult status: idle
    console.log("Change status consult status:", changeStatus.status ) // Change status consult status: success

    If (editConsult.status === "success" && changeStatus.status === "success"){
        router.push("/application");
    }
}

执行onClickAttended时,发现判断条件不生效——editConsult的状态仍为idle,无法触发跳转。


解决方案

核心问题分析

你遇到的问题并非mutateAsync并行执行,而是:

  1. 代码存在语法错误:If应为小写if,直接导致判断逻辑无法运行;
  2. React Query的status状态更新是异步的,在await后立即读取状态,可能还未完成更新。

下面提供两种可靠的解决方式:

方案1:依赖await的成功反馈(推荐)

mutateAsync在请求成功时会返回结果,失败时会抛出异常。因此无需依赖status状态,直接用try/catch包裹两个异步操作,只要都顺利完成就跳转:

const changeStatus = useChangeConsultStatus();
const editConsult = useEditConsulta();

async function onClickAttended() {
  try {
    // 串行执行:先完成编辑请求
    await editConsult.mutateAsync({ consultID: consultID, consult: consultValues });
    // 编辑成功后,再执行状态变更请求
    await changeStatus.mutateAsync({ consultID: consultID, status: "PENDING" });
    
    // 两个请求都成功,执行跳转
    router.push("/application");
  } catch (error) {
    // 任意一个请求失败时,处理错误(如弹窗提示用户)
    console.error("操作失败:", error);
  }
}

方案2:监听状态变更(适合需要状态联动的场景)

如果必须依赖status状态判断,需通过useEffect监听状态变化,确保React已完成状态更新后再执行跳转:

const changeStatus = useChangeConsultStatus();
const editConsult = useEditConsulta();
const router = useRouter();

async function onClickAttended() {
  await editConsult.mutateAsync({ consultID: consultID, consult: consultValues });
  await changeStatus.mutateAsync({ consultID: consultID, status: "PENDING" });
}

// 监听两个请求的状态,当都成功时跳转
useEffect(() => {
  if (editConsult.status === "success" && changeStatus.status === "success") {
    router.push("/application");
    // 跳转后重置状态,避免重复触发
    editConsult.reset();
    changeStatus.reset();
  }
}, [editConsult.status, changeStatus.status, router]);

内容的提问来源于stack exchange,提问作者Miguel Angel Marroquin Jordan

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.18 14:22:39