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

mobx-state-tree中flow包裹的generator函数yield后不恢复执行问题

故障原因与解决方法

该故障90%以上的场景是flow生成器内部代码抛出未捕获异常,且没有对flow返回的Promise做异常捕获,导致错误被静默吞掉,看起来像是yield之后的代码完全没有执行。

常见触发原因

  • 模型字段不匹配:QuestionModel中type、difficulty字段定义为必填枚举类型,若API返回的对应字段值不在枚举范围内、或者字段缺失,在saveQuestions中调用QuestionModel.create时会直接抛出异常,中断后续执行。
  • 数据格式错误:convertedQuestions中存在不符合模型定义的字段值,比如incorrectAnswers不是纯字符串数组、id重复等,都会导致模型创建失败抛错。
  • 无异常捕获逻辑:当前flow函数没有包裹try/catch块,外层调用getQuestions时也没有加catch处理promise拒绝,异常不会输出到控制台,无法感知错误发生。

解决方案

步骤1:添加异常捕获,定位具体错误

先给getQuestions的flow逻辑包裹完整的try/catch,输出错误信息定位根因:

// 修改question-store.ts中的getQuestions action
.actions((self) => ({
  getQuestions: flow(function*() {
    try {
      console.tron.log("GET QUESTIONS");
      const result: GetQuestionsResult = yield self.environment.api.getQuestions();
      console.tron.log("AFTER GET QUESTIONS", result);

      if (result.kind === "ok") {
        self.saveQuestions(result.questions);
      } else {
        __DEV__ && console.tron.log(result.kind);
      }
    } catch (e) {
      __DEV__ && console.tron.error("flow执行错误: ", e.message, e.stack);
    }
  })
}))

同时在调用getQuestions的位置添加catch逻辑,避免异常被吞:

// 调用示例
async function fetchData() {
  try {
    await questionStore.getQuestions()
  } catch (e) {
    console.error('拉取问题列表失败: ', e)
  }
}

步骤2:优化模型定义与数据处理逻辑

优化点1:给非必填枚举字段加兜底

给容易出现值不匹配的枚举字段添加maybe修饰,避免单次数据错误导致整体流程崩溃:

// 修改QuestionModel的props定义
.props({
  id: types.identifier,
  category: types.maybe(types.string), 
  type: types.maybe(types.enumeration(['multiple', 'boolean'])), // 新增maybe修饰
  difficulty: types.maybe(types.enumeration(['easy', 'medium', 'hard'])), // 新增maybe修饰
  question: types.maybe(types.string), 
  correctAnswer: types.maybe(types.string), 
  incorrectAnswers: types.optional(types.array(types.string), []),
  guess: types.maybe(types.string)
})

优化点2:简化saveQuestions逻辑

MST数组的replace方法会自动将符合快照格式的数据转换为模型实例,不需要手动调用QuestionModel.create,避免额外的错误:

saveQuestions: (questionSnapshots: QuestionSnapshot[]) => {
  console.tron.log("保存问题列表", { questionSnapshots });
  self.questions.replace(questionSnapshots);
}

优化点3:数据转换层添加校验

在convertQuestion方法中提前校验字段合法性,不符合要求的字段给默认值,从源头避免无效数据流入模型层。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.30 11:15:01