immutable.js优雅地实现深层字段访问

2018-05-09  本文已影响0人  secViz

在做项目时,很多时候服务端返回的接口嵌套很深,同时每一层是否存在或者为空都是不确定的。因此,为了获得内层的字段通常需要做多次if判断来进行容错,比如下面的这个接口格式:

{
  "data": {
    "Relations": [
      {
        "Instances": [
          {
            "InstanceId": "xx",
            "EipList": ["21.107.32.xx" ]
          }, {
            "InstanceId": "xxxx",
            "EipList": ["21.107.33.xx"]
          }
         ],
        "Domain": "test.com"
      },
      ......
    ]
  }
}

现在需要取出每个 Domain为“test.com”的EipList中的IP集合,在不使用immutable的条件下,通常我们会这么去写(这里采用新语法):

let allEips = [];
if (data.Relations && data.Relations.length > 0) {
    let relations = data.Relations;
    let target = relations.find((elem) => {
        return elem.Domain === "test.com"
    });
    if (target && target.Instances && target.Instances.length > 0) {
        let instances = target.Instances;
        instances.forEach((inst) => {
            let eipList = inst.EipList;
            if (eipList && eipList.length > 0) {
                allEips.push(...eipList);
            }
        });
    }
}
allEips = [...new Set(allEips)];     // 去重
console.log(allEips);                // 输出 [ '21.107.32.xx', '21.107.33.xx' ]

现在我们引入immutable.js来处理这个问题:

import { fromJS, List, Map } from 'immutable';

const immutableData = fromJS(data);
const target = immutableData.get('Relations', List()).find(relation => relation.get('Domain') === "test.com", null, Map());
const eips = target.get('Instances', List()).map(inst => inst.get('EipList', List())).flatten(true);
const allEips = eips.toJS();
console.log(allEips);      // 输出  ["21.107.32.xx", "21.107.33.xx"]

Bingo!!! 深层嵌套不见了,整个代码架构变成了扁平化的结构,因为用immutable.js可以直接访问深层字段,并且可以在每一层设置默认值。

使用immutable.js实现深层字段访问和容错处理其实是大材小用,其真正的牛逼之处在于持久化数据结构,在使用旧数据创建新数据时,能够保证旧数据可用且不变,可以给React应用带来极大的性能提升。

有兴趣的话可以阅读下面的网站进行深入了解:
Immutable 详解及 React 中实践
immutable官方文档

上一篇 下一篇

猜你喜欢

热点阅读