type
Post
status
Published
date
Mar 6, 2020
slug
summary
可选链式调用与空值合并运算符
tags
ECMAScript
JavaScript
category
技术分享
icon
password
可选链式调用与空值合并运算符
正常返回的数据结构
const interfaceList = [ { id: 1104, name: 'onlinemq1:tp_mdm_user:broker-dev:1', data: { avgRt: 75.48, avgRtComparePrev: '-19.28%', hitCount: 42, }, }, { id: 1102, name: 'ymmoa:oabbsService_1.0.0:selectValidChildrenBlocks()', data: { avgRt: 13.34, avgRtComparePrev: '39.92%', hitCount: 116, }, }, ];
然后我们就这样写了
{ interfaceList.map(inter => ( <div key={inter.id}> <div>接口名:{inter.name}</div> <div>请求量:{inter.data.hitCount}</div> <div>平均响应时间:{inter.data.avgRt}</div> <div>平均RT环比昨日:{inter.data.avgRtComparePrev}</div> </div> )); }
异常非正常返回的数据结构
const interfaceList = [ { // 情况 1 id: 1101, name: 'onlinemq1:tp_mdm_user:broker-dev:1', data: { avgRt: 0, avgRtComparePrev: '0.00%', hitCount: 0, }, }, { // 情况 2 id: 1102, name: 'ymmoa:oabbsService_1.0.0:selectValidChildrenBlocks()', data: { avgRt: null, avgRtComparePrev: '', hitCount: null, }, }, { // 情况 3 id: 1102, name: '/cat/r/p', data: {}, }, { // 情况 4 id: 1102, name: '/cat/r/p', data: null, }, { // 情况 5 id: 1102, name: '/cat/r/p', }, ]; const interfaceList = null; // 情况6
问题开始暴露
// 情况 1 暂时没问题 // 情况 2 空白 // 情况 3 空白 // 情况 4 ❌ Uncaught TypeError: Cannot read property 'XXX' of null // 情况 5 ❌ Uncaught TypeError: Cannot read property 'XXX' of undefined { interfaceList.map(inter => ( <div key={inter.id}> <div>接口名:{inter.name}</div> <div>请求量:{inter.data.hitCount}</div> <div>平均响应时间:{inter.data.avgRt}</div> <div>平均RT环比昨日:{inter.data.avgRtComparePrev}</div> </div> )); }
展示’-’,表示暂无数据
// 情况 1 ❌ 数据为 0 也成了暂无数据 // 情况 2 暂时没问题 // 情况 3 暂时没问题 // 情况 4 ❌ Uncaught TypeError: Cannot read property 'XXX' of null // 情况 5 ❌ Uncaught TypeError: Cannot read property 'XXX' of undefined { interfaceList.map(inter => ( <div key={inter.id}> <div>接口名:{inter.name}</div> <div>请求量:{inter.data.hitCount || '-'}</div> <div>平均响应时间:{inter.data.avgRt || '-'}</div> <div>平均RT环比昨日:{inter.data.avgRtComparePrev || '-'}</div> </div> )); }
解决情况 1、4、5
// 情况 1 暂时没问题 // 情况 2 ❌ avgRtComparePrev 是 '' 表示没数据 // 情况 3 暂时没问题 // 情况 4 暂时没问题 // 情况 5 暂时没问题 { interfaceList.map(inter => ( <div key={inter.id}> <div>接口名:{inter.name}</div> <div> 请求量: {inter.data !== null && inter.data !== undefined && inter.data.hitCount !== null && inter.data.hitCount !== undefined ? inter.data.hitCount : '-'} </div> <div> 平均响应时间: {inter.data !== null && inter.data !== undefined && inter.data.avgRt !== null && inter.data.avgRt !== undefined ? inter.data.avgRt : '-'} </div> <div> 平均RT环比昨日: {inter.data !== null && inter.data !== undefined && inter.data.avgRtComparePrev !== null && inter.data.avgRtComparePrev !== undefined ? inter.data.avgRtComparePrev : '-'} </div> </div> )); }
优化
// 情况 1 没问题 // 情况 2 没问题 // 情况 3 没问题 // 情况 4 没问题 // 情况 5 没问题 { interfaceList.map(inter => ( <div key={inter.id}> <div>接口名:{inter.name}</div> <div> 请求量: {inter.data !== null && inter.data !== undefined && inter.data.hitCount !== null && inter.data.hitCount !== undefined ? inter.data.hitCount : '-'} </div> <div> 平均响应时间: {inter.data !== null && inter.data !== undefined && inter.data.avgRt !== null && inter.data.avgRt !== undefined ? inter.data.avgRt : '-'} </div> <div> 平均RT环比昨日: {inter.data !== null && inter.data !== undefined && inter.data.avgRtComparePrev ? inter.data.avgRtComparePrev : '-'} </div> </div> )); }
再优化
{ interfaceList.map(inter => ( <div key={inter.id}> <div>接口名:{inter.name}</div> <div> 请求量: {!_.isNil(inter.data) && !_.isNil(inter.data.hitCount) ? inter.data.hitCount : '-'} </div> <div> 平均响应时间: {!_.isNil(inter.data) && !_.isNil(inter.data.avgRt) ? inter.data.avgRt : '-'} </div> <div> 平均RT环比昨日: {!_.isNil(inter.data) && inter.data.avgRtComparePrev ? inter.data.avgRtComparePrev : '-'} </div> </div> )); }
既然都用了 lodash
{ interfaceList.map(inter => { // 不推荐使用 get 的第三个参数设置默认值,因为只有在 undefined 的时候才会设置,null 被认为是有值的 const hitCount = _.get(inter, 'data.hitCount'); const avgRt = _.get(inter, 'data.avgRt'); const avgRtComparePrev = _.get(inter, 'data.avgRtComparePrev'); return ( <div key={inter.id}> <div>接口名:{inter.name}</div> <div> 请求量: {!_.isNil(hitCount) ? hitCount : '-'} </div> <div> 平均响应时间: {!_.isNil(avgRt) ? avgRt : '-'} </div> <div> 平均RT环比昨日: {avgRtComparePrev || '-'} </div> </div> ); }); }
用 optional chain 替换掉 _.get()
// 情况 1 暂时没问题 // 情况 2 暂时没问题 // 情况 3 暂时没问题 // 情况 4 暂时没问题 // 情况 5 暂时没问题 { interfaceList.map(inter => ( <div key={inter.id}> <div>接口名:{inter.name}</div> <div> 请求量: {!_.isNil(inter.data?.hitCount) ? inter.data?.hitCount : '-'} </div> <div> 平均响应时间: {!_.isNil(inter.data?.avgRt) ? inter.data?.avgRt : '-'} </div> <div> 平均RT环比昨日: {inter.data?.avgRtComparePrev || '-'} </div> </div> )); }
用 nullish coalescing operator 替换掉 _.isNill
// 情况 1 暂时没问题 // 情况 2 暂时没问题 // 情况 3 暂时没问题 // 情况 4 暂时没问题 // 情况 5 暂时没问题 { interfaceList.map(inter => ( <div key={inter.id}> <div>接口名:{inter.name}</div> <div> 请求量: {inter.data?.hitCount ?? '-'} </div> <div> 平均响应时间: {inter.data?.avgRt ?? '-'} </div> <div> 平均RT环比昨日: {inter.data?.avgRtComparePrev || '-'} </div> </div> )); }
情况 6 来了
{ interfaceList?.map(inter => ( <div key={inter.id}> <div>接口名:{inter.name}</div> <div> 请求量: {inter.data?.hitCount ?? '-'} </div> <div> 平均响应时间: {inter.data?.avgRt ?? '-'} </div> <div> 平均RT环比昨日: {inter.data?.avgRtComparePrev || '-'} </div> </div> )); }
这么爽!我能用了吗?
- TypeScript 3.7 supports Optional Chaining & Nullish Coalescing
- Babel 7.8.0 supports Optional Chaining & Nullish Coalescing
- @babel/proposal-optional-chaining,
- @babel/proposal-nullish-coalescing-operator
- 作者:Wave52
- 链接:https://vercel.wuchengran.com/article/cca0f6a5-41c9-4774-9042-345579068cb9
- 声明:本文采用 CC BY-NC-SA 4.0 许可协议,转载请注明出处。
相关文章