策略设计
背景
在自定义控件中,如果想和后端做数据交互,需要借助全局对象 model 的 API 调用才行,例如:
model.invoke("click", "Hello World!");
想要了解更多关于
model的信息,请参考 360° 教你搞定“自定义控件”(API 手册篇),如果链接失效了,请从右上角的社区链接进入,然后自行搜索~
当后端返回数据时,会触发控件注册时的 update 方法,从而获取到返回的数据。
这种方式对于开发阶段的时候会带来两点不便之处:
如果我们的组件数量多,嵌套也多,获取数据会特别麻烦,要么层层传递,要么使用订阅发布模式,要么使用状态管理工具监听。然而这些都不是好的方法。
在咱们的 RAM 模式开发时,根本就没有
model这个全局对象,无法调用异步请求。
如果有一个统一的 API 方法调用,并且支持 Promise、Await 写法,那么就可以很方便地解决上述问题。于是我设计了一个请求策略来模拟 Promise 行为,并且提供了两种请求模式。
请求模式的设计
假设我们有几个不同的请求方法/任务,例如 a, b, c 。但同一个请求方法可能会被陆续请求多次,所以同一个请求方法的不同时间触发会在后面加数字表示,例如 a1, a2, a3 。
单队列(默认采用)
单线请求模式,设计了一个队列来保存请求方法,每次请求都会将请求方法添加到队列中,然后依次执行队列中的请求方法。
每次请求只能执行一个,其他请求需要排队等待。
例如依次发送请求 a1, a2, b1, c1 ,此时请求队列中会是 [a1, a2, b1, c1] ,a1 先弹出执行,并且等待 a1 对应的 update 触发并执行完成后,a1 任务才算彻底结束,开启 a2 请求,以此类推。
这样做的理由是保证 update 触发的时候能够跟队列里的请求任务对应上,这样任务返回的数据才能匹配对。
这个模式不足之处是:
如果
a1请求很慢,那么a2都要等待a1请求结束才能开始执行。不同任务无法并发执行。
多队列(推荐)
并行请求模式。不同的请求方法可以并行请求。设计是给不同的请求方法/任务分配不同的请求队列。
例如依次发送请求 a1, a2, b1, c1 ,此时请求队列中会是与 a 方法相关的单独一个队列 [a1, a2] ,其他为 [b1] 、 [c1] 的队列。这样不同的方法就可以并行发送。
如果采用多队列模式,后端必须在 data 字段中多返回一个字段表示请求的方法名称,这样前端才知道该请求是哪个方法,不同队列才能匹配到对应数据,精确结束任务。
开启多队列模式需要在全局设置中设置 REQUEST_MODE 为 concurrent(默认为单队列 single ) ,UPDATE_METHODS_FIELD 填写后端请求的方法名称字段名。
接口请求书写方式
综上两种队列模式的设计,我对 model.invoke 进行了封装,模拟出了 Promise 行为。并且支持在 RAM 模式下使用(通过 Axios 或者 Websocket 与 Mock 服务交互)。
具体使用方式参考:
遗憾 😪
对于那种不是前端主动要的,而是后端主动推动的数据,由于在队列种没有对应任务,所以无法通过 API 去获取数据,目前的做法是帮开发者捕获到,但让开发者自行选择方案数据传递的方案。
具体代码位置需要参考后面 React18 和 Vue3 章节的接口请求书写方式。