NgRx Store createSelector 返回的 selector 执行取数逻辑的单步调试

举报
汪子熙 发表于 2022/08/01 21:41:09 2022/08/01
【摘要】 测试源代码:import { Component } from '@angular/core';import { createSelector } from '@ngrx/store'; export interface State { counter1: number; counter2: number;} export const selectCounter1 = (state: S...

测试源代码:

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,返回之。

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。