UnderscoreJS与MomentJS过滤动态数组返回空问题排查
我来帮你排查这个问题,这种动态数组过滤无结果但静态数组正常的情况,通常是异步时机、日期格式或者数据组装环节出了问题,咱们一步步拆解解决:
排查与解决动态数组过滤无结果的问题
1. 先解决最常见的异步时机问题
AJAX请求是异步执行的,如果你在AJAX的success回调外面调用过滤逻辑,那时候receivedDataThree还没被接口返回的数据填充,自然会得到空数组。
错误示例(时机不对)
var receivedDataThree = []; $.ajax({ type: "GET", dataType: "JSON", url: 'https://famagas-api.herokuapp.com/api/itapeCompanyNews', success: function(allResponseThree) { // 这里才会填充数组 receivedDataThree = allResponseThree.map(item => ({ dateOfPurchased: item.dateField, // 假设接口返回的日期字段是dateField // 其他字段组装 })); } }); // 这里执行过滤时,receivedDataThree还是空数组! var sortDate = _.filter(receivedDataThree, function(desc) { return moment(desc.dateOfPurchased).isAfter(moment(todayDate).subtract(30, 'days')) });
正确解法(把过滤放在回调内)
把过滤逻辑移到success回调里,确保数组已经被填充后再执行过滤:
var receivedDataThree = []; $.ajax({ type: "GET", dataType: "JSON", url: 'https://famagas-api.herokuapp.com/api/itapeCompanyNews', success: function(allResponseThree) { // 先完成数据组装 receivedDataThree = allResponseThree.map(item => ({ dateOfPurchased: item.dateOfPurchased, // 要和接口返回的字段名完全一致 // 其他字段 })); // 在这里执行过滤! var todayDate = moment(); // 确保todayDate是有效的Moment实例 var sortDate = _.filter(receivedDataThree, function(desc) { return moment(desc.dateOfPurchased).isAfter(todayDate.subtract(30, 'days')) }); // 现在sortDate应该能拿到正确结果了 console.log('过滤后的近30天数据:', sortDate); } });
2. 检查dateOfPurchased的格式是否合法
静态数组的日期格式是Moment能识别的,但接口返回的日期可能存在格式异常(比如是DD/MM/YYYY而非标准的YYYY-MM-DD、是时间戳字符串、甚至是空值/undefined),导致Moment解析失败,过滤条件永远不成立。
验证方法
在success回调里先打印检查每一项的日期有效性:
success: function(allResponseThree) { receivedDataThree = allResponseThree.map(item => ({ dateOfPurchased: item.dateOfPurchased, // 其他字段 })); // 逐一验证日期是否能被Moment解析 receivedDataThree.forEach(item => { const dateValid = moment(item.dateOfPurchased).isValid(); console.log(`日期值: ${item.dateOfPurchased} | 是否有效: ${dateValid}`); }); // 过滤时跳过无效日期 var todayDate = moment(); var sortDate = _.filter(receivedDataThree, function(desc) { const date = moment(desc.dateOfPurchased); // 先排除无效日期,再判断是否在近30天内 return date.isValid() && date.isAfter(todayDate.subtract(30, 'days')); }); }
如果发现无效日期,需要指定Moment的解析格式,比如接口返回的是"DD/MM/YYYY":
moment(desc.dateOfPurchased, "DD/MM/YYYY")
3. 确认todayDate的定义是否正确
如果todayDate不是有效的Moment实例(比如是普通字符串、格式错误的日期),todayDate.subtract(30, 'days')会生成无效日期,导致过滤逻辑失效。
确保todayDate是正确的Moment对象:
// 正确:获取当前日期 var todayDate = moment(); // 或者如果是指定日期,要保证能被解析 var todayDate = moment("2024-05-20");
4. 检查数据组装逻辑是否正确
可能在组装receivedDataThree时,dateOfPurchased字段没有被正确赋值:比如字段名拼写错误(把接口返回的dateOfPurchase写成了dateOfPurchased)、或者没有从allResponseThree的正确属性中取值。
可以先打印原始接口数据确认字段名:
success: function(allResponseThree) { console.log('接口原始返回数据:', allResponseThree); // 再根据实际字段名组装数据 receivedDataThree = allResponseThree.map(item => ({ dateOfPurchased: item.dateOfPurchased, // 要和接口返回的字段完全匹配 // 其他字段 })); }
内容的提问来源于stack exchange,提问作者smachs
相关产品推荐
相关产品推荐

