JQuery.Deferred过滤器异常处理:筛选完成后再执行数据赋值操作
问题根因
- 你遇到的报错和筛选、赋值的执行顺序无关,
Array.filter是JS内置的同步方法,会同步执行完所有筛选逻辑后才会执行后续的赋值代码 - 报错的核心原因是:当
dataset1中不存在和当前mapdata.id匹配的项时,filter方法会返回空数组,此时dataset1filter[0]的值为undefined,访问undefined的name属性就会抛出你看到的类型错误
修复方案
我们只需要在赋值前增加筛选结果的非空判断即可,如果需要兼容匹配不到的场景,可以增加默认值兜底:
var activitydata = function(allactivitiesObj) { allactivitiesObj.dataset = allactivitiesObj.dataset.map(function(mapdata) { // 两个筛选逻辑是同步执行,执行完才会走后续逻辑 var dataset2filter = dataset2.filter(function(data) { return data.id === mapdata.id; }); var dataset1filter = dataset1.filter(function(data) { return data.id === mapdata.id; }); // 增加非空判断,匹配到结果再赋值,可自定义兜底逻辑 if (dataset1filter.length > 0) { mapdata.dataset = dataset1filter[0].name; } else { // 匹配不到时的兜底逻辑,可按需修改,比如赋值为空字符串 mapdata.dataset = ''; } return mapdata; }); return allactivitiesObj }
如果业务逻辑要求必须同时匹配到dataset2和dataset1的结果才赋值,可以进一步修改判断条件:
// 双筛选结果都存在才赋值 if (dataset1filter.length > 0 && dataset2filter.length > 0) { mapdata.dataset = dataset1filter[0].name; // 如果需要用到dataset2的结果也可以在这里处理 }
额外优化建议
你当前的筛选逻辑只要取第一个匹配的项,可以用Array.find替代Array.filter,不用生成完整的匹配数组,性能更好,写法也更简洁:
var activitydata = function(allactivitiesObj) { allactivitiesObj.dataset = allactivitiesObj.dataset.map(function(mapdata) { var matchDataset2 = dataset2.find(function(data) { return data.id === mapdata.id; }); var matchDataset1 = dataset1.find(function(data) { return data.id === mapdata.id; }); // find没匹配到会直接返回undefined,判断即可 if (matchDataset1) { mapdata.dataset = matchDataset1.name; } else { mapdata.dataset = ''; } return mapdata; }); return allactivitiesObj }
内容的提问来源于stack exchange,提问作者fdz
相关产品推荐
相关产品推荐

