作者:飞羽
本文简述:通过对一个开发简单的模块,将iMove带入你的编程世界。
从前,有一个需求
/做一个天气组件的功能。
一、需求收集
产品的需求描述很简单,天气 widget组件:展示当前用户所在地的天气,可以自己选择地址查询天气。
但是实际上会有很多隐藏的需求:
- 功能一:初始化获取经纬度,通过经纬度查城市ID,通过城市ID查天气。
- 功能二:通过城市ID 查询天气API。
但是产品经理多数可能没有考虑到 “边界情况”、“异常情况”。
- 如何手机所在的地址:通过手机定位GPS信息
- 如果GPS 没有怎么办?
- 城市ID 获取不到怎么办?
二、分析需求
这个需求本质上是:
- 请求一些API,拿到我们想要的数据
- 考虑一些异常情况和边界情况
- 输出到视图展示。
- 任务完成!
三、准备工作
在开始写代码之前,我们要做一些准备工作,如:安装iMove、以及了解一下 iMove 的简单工作原理。
- Mac一台,没有Mac,理论上PC也能开发。
新建工程:这里使用 react-app 来创建我们的工程
npm init react-app my-app
cd my-app
确保你的项目目录中有 package.json 和 src 目录。
初始化 iMove 本地构建器:见 iMove 开发套件 ( https://github.com/imgcook/imove )
imove -i
启动 imove 本地构建器
imove -d
打开 imove GUI 地址(也可以本地运行):https://65hzt.sse.codesandbox.io
你将看到如下iMove 界面,目前还是比较简陋,但是已经足够满足本文的需求了。
在右上角:提示本地连接成功

不做任何操作,保存(Ctrl+S)后:将在你的开发目录中生成对应 logic 目录。
此时,还没有任何逻辑,我们的开发目录中已经生成了iMove 的 logic出码文件夹,让人非常的安心。
四、运行 hello iMove
此时我们拖入一个开始节点(后面有说明节点的类型)
并且点击“编辑”,可以打开代码编辑界面。输入“hello iMove”
然后点保存。这个时候代码会同步到你的开发目录如下:
(不要介意那个像hash一样的文件名,你会习惯的 >///< )
如果需要运行 这部分逻辑,只需要 在你的 react 组件中引用 logic.js ,两行代码就能实现。
import Logic from './logic';
Logic.invoke('start'); // 'start' 为逻辑触发名称
五、添加 iMove 节点
然后我们回到 iMove 界面,增加如下几个节点,并且将其链接起来如下:
分别在 “判断节点”、“处理节点” 添加如下代码
// 开始
export default async function(ctx) {
const message = 'hello iMove ~';
console.log(message);
return { message }
}
// 是否成功
export default async function(ctx) {
return true;
}
// 请求成功
export default async function(ctx) {
console.log('成功', ctx.getPipe());
}
// 请求失败
export default async function(ctx) {
console.log('失败', ctx.getPipe());
}
然后继续回到 react app 你发现页面运行的时候,输出产生了变化~
可以看到 变量 message 通过 “判断节点” 被传递到了 请求成功 节点。你可以想象水流一样。
这个时候我们把“判断节点” 改个方向 如下:
// 判断是否成功
export default async function(ctx) {
return false;
}
然后看控制台,神奇的事情发生了:
“判断节点” 就像开关一样将 水流(pipe) 导向你想要的地方
是不是非常好理解,这个就是 iMove 的基础特性! Amazing ! ~~
六、监听数据
可以控制流程之后,那么如何监听触发流程的结果以及状态呢?
继续上面的流程。
我们在 “请求成功”、“请求失败”节点 分别添加一行代码,如下:
// 请求 成功
export default async function(ctx) {
console.log('成功', ctx.getPipe());
ctx.emit('action', { status: 'SUCCESS' });
}
export default async function(ctx) {
console.log('失败', ctx.getPipe());
ctx.emit('action', { status: 'FAIL' });
}
然后在你的 react 组件中添加 监听脚本:
import Logic from './logic';
// 监听 action 事件
Logic.on('action', payload => {
console.log(payload);
});
// 'start' 为逻辑触发名称
Logic.invoke('start');
这个时候 控制台就能 捕获到 你触发的 action 事件以及数据。
看到这里大概就能了解iMove的核心工作方式:
- 开始节点:**黑色**的圆形,代表事件流的开端。
- 流程节点:蓝色的长方形,事件流的 信息输入节点 (可以给pipe流里注入数据)
- 判断节点:黄色的菱形,事件流的 导流器 (类似:铁路的转向装置,将pipe数据引导至正确的方向)
- 广播节点:绿色的长方形,事件流的 广播节点,负责将 数据流 广播给视图层
有了以上简单理解后,就可以清晰了解 每个节点该做什么,不该做什么。
六、绘制逻辑
可以通过复制以下数据导入(高级功能,见DSL导入):
以下是流程的DSL:
https://github.com/qilei0529/imove-example/blob/master/.cache/imove_empty.dsl.json
七、编写补全逻辑
以下是补全代码后的DSL:
https://github.com/qilei0529/imove-example/blob/master/.cache/imove.dsl.json
八、连接视图
通过iMove 绘制的图 我们可以清楚的知道在哪里获取数据,从哪里提取异常。
比如:如果要获取,天气数据只需要监听 iMove 中的“请求天气成功”事件就可以。
// 监听 action 事件
Logic.on('action', payload => {
const {
type,
weather
} = payload;
if (type === 'SUCCESS') {
setState({
status: '2', // 模块状态:0 初始 1 加载中 2 正常 4 异常
weather, // 天气数据
})
}
});
九、注意事项
- Logic.on 的方法是继承自 EventEmitter ,需要注意它的副作用(重复声明会引起bug)
十、思考 & 展望
可能刚开始上手iMove 的时候,会觉得代码量反而变多了。
但细品,会发现可以做很多有意思的事情,比如:如何将代码节点化? 如何设计好与视图交互的数据结构?
开发方式产生了一些变化?
- 先画流程,再写代码成为新的流程。(很多时候流程画完,代码就已经清晰了)
- 从视觉上将 业务逻辑 节点化。
- 代码的思考过程完全呈现给上下游(后端、测试),再也不怕测试质疑我的代码有问题了。