You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

在Deferred对象中使用$.grep报错:Cannot read property 'value' of undefined

问题分析与解决方案

嘿,这个问题我太熟了——你这明显是异步操作的时序坑在搞鬼!虽然console.log看起来能输出正确值,但那只是浏览器控制台的小把戏(当你展开对象时才会读取最新状态),实际代码执行时,你用来过滤的JSON变量还没被异步请求赋值,所以才会报错。

核心问题拆解

你当前的代码逻辑大概是这样的(简化版):

let targetDateData;

// 第一步:获取大量原始数据
$.get('/your-large-data-url', function(rawResponse) {
  // 第二步:用Deferred异步加载目标JSON文件
  const deferred = $.get('/your-date-json-url');
  deferred.done(function(data) {
    targetDateData = data; // 这里是异步赋值,不会立刻完成
  });

  // 第三步:直接遍历原始数据并过滤,但此时targetDateData可能还是undefined!
  rawResponse.forEach(item => {
    const result = $.grep(targetDateData, obj => obj.date === item.date);
    console.log(result); // 控制台延迟显示,让你误以为值是对的
  });
});

问题就出在第二步的异步赋值还没完成,第三步的过滤逻辑就已经跑起来了,这时候targetDateData要么是undefined,要么还没拿到完整数据,自然会报错。

两种靠谱的解决办法

办法1:把过滤逻辑放进Deferred的回调里

确保等目标JSON数据完全加载完成后,再执行遍历和过滤:

$.get('/your-large-data-url', function(rawResponse) {
  // 先等目标JSON加载完成
  $.get('/your-date-json-url')
    .done(function(targetDateData) {
      // 现在数据肯定准备好了,放心过滤
      rawResponse.forEach(item => {
        const filteredResult = $.grep(targetDateData, obj => obj.date === item.date);
        console.log(filteredResult); // 这里绝对不会报错
      });
    })
    .fail(function() {
      // 别忘了处理JSON加载失败的情况
      console.error('加载日期JSON文件失败了!');
    });
});

办法2:用Promise.all统一等待所有异步请求

如果你的jQuery版本在1.8以上(支持Promise),用链式调用会更优雅,还能同时处理多个异步请求:

// 同时发起两个异步请求,等它们都完成再继续
Promise.all([
  $.get('/your-large-data-url'),
  $.get('/your-date-json-url')
])
.then(function([rawResponse, targetDateData]) {
  // 两个请求都成功返回了,开始过滤
  rawResponse.forEach(item => {
    const filteredResult = $.grep(targetDateData, obj => obj.date === item.date);
    console.log(filteredResult);
  });
})
.catch(function(error) {
  // 任何一个请求失败都会走到这里
  console.error('请求出错了:', error);
});

额外提醒

  • 先看报错信息:如果是Cannot read property 'date' of undefined这类,那百分百是时序问题,不用怀疑。
  • 别用全局变量存异步数据:尽量通过回调参数或者Promise返回值传递数据,减少时序混乱的概率。
  • 加调试日志:可以在targetDateData赋值后加console.log('数据加载完成:', targetDateData),确认数据真的准备好了再执行后续逻辑。

内容的提问来源于stack exchange,提问作者Peter Griffin

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.19 04:25:51