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

Cypress轮询API报错:异步与同步代码混用问题排查

问题分析与解决思路

核心问题

你遇到的错误本质是在Cypress的cy.then()回调中混合了异步命令(cy.wait、cy.log)和同步返回值,同时递归调用时没有正确返回Promise,导致Cypress的命令链无法正确跟踪异步流程。另外你的for循环逻辑存在缺陷:只要第一个item的reason不匹配就直接重试,没有遍历完所有items就发起下一次请求,会错过已经存在目标reason的情况。

具体修复点

  • 修正递归调用的返回逻辑:每次递归调用pollStatusReason时必须return它的结果,确保Cypress能跟踪异步命令链。
  • 调整items遍历逻辑:先遍历所有items检查是否存在目标reason,只有当所有items都不匹配时才发起重试,而不是第一个不匹配就重试。
  • 避免在cy.then()中同步返回值:确保在回调中要么全是异步命令链,要么返回一个Promise(Cypress命令本身就是Promise)。

修正后的代码

function pollStatusReason(id, reason, attempts = 0) {
  const url = `http://someurl/${id}`;

  if (attempts > 30) {
    throw new Error(`Too many attempts to get reason: ${reason}`);
  }

  return cy.request({
    method: 'GET',
    url: url,
  }).then((response) => {
    if (response.status !== 200) {
      // 递归时必须return,保证命令链连续
      return pollStatusReason(id, reason, attempts + 1);
    }

    const items = response.body.items;
    // 先检查所有items是否存在目标reason
    const hasTargetReason = items.some(item => item.reason === reason);

    if (hasTargetReason) {
      expect(reason).to.eq(reason); // 可根据需求调整为更精准的断言,比如断言具体item的reason
      return response;
    } else {
      cy.log(`RETRYING TO GET STATUS REASON: ${reason}`);
      // 等待后必须return递归调用的结果,保证异步流程连贯
      return cy.wait(5000).then(() => {
        return pollStatusReason(id, reason, attempts + 1);
      });
    }
  });
}

export default pollStatusReason;

补充说明

  • 使用Array.some()替代for循环,更简洁地检查是否存在目标reason,避免遍历中断的问题。
  • 将cy.wait(5000)包装在cy.then()中并返回递归结果,确保异步等待后再发起下一次请求,符合Cypress的命令链规则。
  • 抛出错误时使用Error对象,比字符串更规范,便于Cypress捕获和展示错误信息。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.03 22:36:20