解决umi.js或dva.js中effect函数发生错误dispatch失效的问题

问题背景

在项目的model文件中,通常在effect中进行网络请求等异步操作,当网络错误或者请求结果错误时,以及代码语法错误时,无论是否主动使用throw语句抛出错误,下一次再调用dispatch访问effect中的函数时,均会失效。

问题复现

  1. 编辑完表单后通过dispatch 访问model中effects中的edit函数
    在这里插入图片描述
  2. edit 方法中进行网络请求,更新表单数据等操作
    在这里插入图片描述
  3. 此时发生了网络错误,或者服务端异常,返回5xx状态的错误结果。控制台的打印结果为:
    在这里插入图片描述
    此时系统界面上的表现一切正常,加载状态正常结束,页面提示也正常,理论上等待网络或者服务器正常之后再次点击按钮,重新执行一遍流程就能返回正常结果
  4. 但是,结果如下
    在这里插入图片描述
    dispatch函数没有成功执行,甚至都没有进入到effects的edit函数中,也没有发起网络请求,界面发生了死锁。
    而且经过测试,此时访问其他的effects函数同样会失效,但是能够正常访问reducers函数。
  5. 总结一下,错误的发生条件:
    1)effects函数中发生错误,但是没有捕获。
    2)捕获错误之后,使用throw关键字抛出。(不抛出就没问题)

原因分析

在问题复现的第三步中,有两个值得注意的输出:

  1. 第一个是dispatch 的返回值,是一个pending 状态的promise对象,而且经过测试在这个dispatch之后使用.then/.catch 都不能正常运行。而在effect函数正常执行时,这个返回的promise对象的状态是fulfilled
    在这里插入图片描述
    由此推测,dispatch 失效的原因应该是 umi/dva 在dispatch实现的时候做了错误的兜底捕获,并在发生这种未捕获的错误时改变自身的状态,并在下一次被调用时阻止调用。then方法无法执行的原因应该也是内部做了二次封装,返回的对象并不是一个典型的promise对象。但这些都是主观推测,等有空了研究下dispatch的源码。
  2. 另一个值得注意的是最后输出的一段奇怪的报错信息,明显与正常的js代码报错不同:
    在这里插入图片描述
  3. 反思了下项目的设计,在发生错误或者抛出错误之后,没有做全局错误的兜底捕获,这明显是不对的,很有可能造成项目的崩溃,而且也不方便错误的定位。

解决方法

搜索上诉的报错信息发现有现成的解决方案:
umi项目中报错uncaught at _callee3 at _calle3
其他解决方案:
使用dva中函数,如果返回错误结果,再次调用,dispatch无响应
总结一下,主要有两个方案:

  1. 使用try...catch... 主动捕获可能发生错误的代码,并进行手动处理,不要使用 throw 再次抛出。
  2. 使用 dva 框架自带的 onError 全局错误管理函数,捕获错误并处理。

Dva文档中的描述:
在这里插入图片描述
Umi文档中的描述:
在这里插入图片描述

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: Umi.js 项目和 Django 项目的连接通常是通过 API 实现的。 首先,需要在 Django 项目配置好 RESTful API,以便 Umi.js 项目可以通过 API 与其进行数据交互。 其次,在 Umi.js 项目使用 Axios、Fetch 或其他网络请求库向 Django 项目的 API 发送请求,以获取数据并完成与 Django 项目的交互。 最后,可以使用 Redux、Mobx 等状态管理工具管理 Umi.js 项目的数据状态,以保证数据的一致性和可靠性。 总的来说,Umi.js 项目与 Django 项目的连接实现起来比较简单,需要了解 RESTful API 和网络请求的基本知识。 ### 回答2: Umi.js是一个基于React的前端开发框架,而Django是一个使用Python的后端开发框架。要将Umi.js项目与Django项目连接起来,可以按照以下步骤进行: 1. 创建Django项目:首先,使用Django的命令行工具创建一个Django项目。在终端运行命令 `django-admin startproject myproject`,其"myproject"是你想要的项目名称。 2. 创建Django应用程序:接下来,在项目的目录创建一个Django应用程序。在终端运行命令 `python manage.py startapp myapp`,其"myapp"是你想要的应用程序名称。 3. 配置路由:在Django项目,你需要配置URL路由来处理来自Umi.js项目的请求。在Django项目的主文件urls.py,添加相应的路由配置。 4. 配置视图:接下来,在Django应用程序的views.py文件编写视图函数来处理Umi.js项目发送的请求。在视图函数,你可以根据具体需求进行数据处理、数据库操作等操作,并返回相应的数据给Umi.js项目。 5. 配置模型:如果你的项目需要与数据库交互,可以在Django应用程序的models.py文件定义模型类,用于与数据库表进行映射。通过模型类,你可以方便地进行数据库的增删改查操作。 6. 配置Umi.js项目:在Umi.js项目,通过配置代理将请求转发到Django项目的服务器。在.umirc.js配置文件,添加proxy配置项,将请求代理到Django项目的服务器地址。 7. 发送请求:在Umi.js项目的组件,使用fetch、axios或者其他类似的工具发送请求给Django项目的服务器。根据你在Django项目配置的路由和视图,将得到相应的数据。 通过以上步骤,你可以实现Umi.js项目与Django项目的连接,前端通过发送请求到后端,后端处理数据并返回给前端展示。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值