共计 1310 个字符,预计需要花费 4 分钟才能阅读完成。
测试源代码:
import {Component} from '@angular/core';
import {createSelector} from '@ngrx/store';
export interface State {
counter1: number;
counter2: number;
}
export const selectCounter1 = (state: State) => state.counter1;
export const selectCounter2 = (state: State) => state.counter2;
export const selectTotal = createSelector(
selectCounter1,
selectCounter2,
(counter1, counter2) => counter1 + counter2
); // selectTotal has a memoized value of null, because it has not yet been invoked.
let state = {counter1: 3, counter2: 4};
@Component({
selector: 'selector',
template: ''
})
export class SelectorComponent{constructor(){console.log(selectTotal(state)); // computes the sum of 3 & 4, returning 7. selectTotal now has a memoized value of 7
console.log(selectTotal(state)); // does not compute the sum of 3 & 4. selectTotal instead returns the memoized value of 7
}
}
首先执行构造函数里第一条 selector 调用。
selectTotal 的函数体就是 createSelector 返回的 memoized 函数:
因为是第一次调用,lastArguments 为 undefined,因而执行 projectionFn:
还不会马上调用到咱们在 projection 里定义的加法运算:
这里还看不到咱们应用程序里传入 createSelector 时指定的 projectionFn 函数。
selectors 是数组,外面寄存了利用开发人员传入的纯函数:
调用数组自带的 map 办法,首先把 projection 计算所需的输出参数计算出来:
此处 fn 即 selectors 数组第一个元素:
失去 3:
顺次类推,第二个参数 4:
3 和 4 即为最终调用带有记忆性能的 projectionFn 的输出参数:
这就是咱们曾经熟知的 memoized 函数体了。能够参考 Jerry 之前的文章:NgRx Store createSelector 的单步调试和源代码剖析。
projector 就是之前 createSelector 传入的纯函数的最初一个,即执行加法运算的 函数:
执行求和运算:
将调用的输出参数 3 和 4 缓存起来。一并缓存的还有计算结果 7:
第二次执行时,因为输出参数未变,依然是 3 和 4,故间接从缓存后果里取出 7,返回之。
更多 Jerry 的原创文章,尽在:” 汪子熙 ”:
正文完