开启掘金成长之旅!这是我参与「掘金日新计划 · 2 月更文挑战」的第 10 天,点击查看活动详情
背景
本文记录笔者实现 mini-vue3 项目中 effect函数 返回 runner函数 的功能。
思路
书接上回 「mini-vue3」实现 reactive & effect 的「收集依赖/触发依赖」功能,我们已经实现了一个基本的 effect 模块,接下来添加一点功能,同样地,我们用测试驱动开发的思路来做,编写测试如下:
effect函数接收一个fn函数,首次执行effect时,执行一次fn。- 执行
effect会返回一个runner函数,执行runner时,再次执行fn。 - 执行
runner后,返回fn的返回值。
编写代码
编写测试用例
在 effect.spec.ts 中通过 it 增加测试用例:
describe('effect', () => {
// ...
it('should return runner when call effect', () => {
let foo = 10;
// effect 函数接收一个 fn 函数
const runner = effect(() => {
foo++;
return 'runner';
})
// 测试1: 首次执行 effect 时,执行一次 fn。
expect(foo).toBe(11);
const r = runner();
// 测试2: 执行 runner 时,再次执行 fn。
expect(foo).toBe(12);
// 测试3: 执行 runner 后,返回 fn 的返回值。
expect(r).toBe('runner');
})
}
测试驱动开发
根据测试用例来编写项目代码,在 effect.ts 中,先让 effect 函数返回一个 runner 函数,这个 runner 函数要能执行 fn,其实就是 ReactiveEffect 里的 run 方法。
由于 run 方法里使用了 this,所以这里返回函数前要把 _effect 绑定到 this 上。
export function effect(fn: Function) {
const _effect = new ReactiveEffect(fn);
_effect.run();
// 执行 effect 会返回一个 runner 函数,执行 runner 时,再次执行 fn。
return _effect.run.bind(_effect);
}
执行 runner 后要返回 fn 的返回值,所以修改如下:
// ...
class ReactiveEffect {
private _fn: Function;
constructor(fn: Function) {
this._fn = fn;
}
// runner 函数
public run(): void {
if (!this._fn) return;
activeEffect = this;
// 执行 runner 后,返回 fn 的返回值。
return this._fn();
}
}
// ....
通过 jest 执行测试
执行 yarn test effect,测试本文新增用例 should return runner when call effect,结果如下:
可以看到,测试通过 ✅,功能已实现 🎉
总结
本文实现 effect函数 返回 runner函数 的功能,本步骤完整代码可在笔者的远程库 ---- mini-vue3: 执行 effect 返回 runner 函数 中查看。