Runner
我们已经完成了响应式的整个流程,并已经达到数据改变的时候相关值也会跟着变化,今天我们就来处理一下effect函数的返回,之前,我们仅仅处理了如何调用effect传入的fn。
单测
接下来,我们还是看一个单测,便于我们了解什么是我们所说的runner。
// src/reactivity/effect.spec.ts
describe("effect", () => {
...
it ('should return runner when call effect', () => {
let foo = 10
// 将effect执行完之后返回的值赋值给runner
const runner = effect(() => {
foo ++
return 'foo'
})
expect(foo).toBe(11)
// 从这里,我们知道effect返回的是一个function,并且也有返回值
const r = runner()
// 到这一步,我们知道执行runner之后数值会更新,这个runner就是我们传入effect的fn
expect(foo).toBe(12)
expect(r).toBe('foo')
})
})
我们一起来分析上面的测试用例,从中我们可以得到3条信息
-
1、
effect执行结果会返回一个function,我们称之为runner。 -
2、我们可以接收
runner返回的值,也就是说我们可以获取effect(fn)中fn的返回值 -
3、当我们执行
runner的时候,会再次执行fn函数
编码
根据上面的结论,我们开始一步步来实现。
1、处理effect的返回值
这里,我们之所以要用bind指定_effect.run函数的this指向,是因为在ReactiveEffect的run方法中,我们将this赋值给了activeEffect,为了避免this指向出问题。
export function effect (fn) {
...
return _effect.run.bind(effect)
}
2、处理ReactiveEffect中返回值
我们直接在run中返回this._fn()的执行结果即可。
class ReactiveEffect {
...
public run () {
activeEffect = this
return this._fn()
}
}
上面就是所有关于runner的的代码
测试结果
PS D:\user\desktop\mini-vue> yarn test
yarn run v1.22.10
$ jest
PASS src/reactivity/tests/effect.spec.ts
PASS src/reactivity/tests/reactive.spec.ts
PASS src/reactivity/tests/index.spec.ts
Test Suites: 3 passed, 3 total
Tests: 4 passed, 4 total
Snapshots: 0 total
Time: 0.988 s, estimated 1 s
Ran all test suites.
Done in 2.21s.
总结
这里,我们可能还不大了解runner到底有啥用处,到了后面会慢慢理解,我们先理解runner的逻辑实现,以及他能干什么即可。