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

JavaScript跨函数访问对象遇异常:空对象或Promise <pending> 排查

问题分析与解决方案

你的问题核心在于异步代码的执行顺序以及全局变量的时机问题,咱们一步步拆解清楚:

为什么会得到空对象或Promise { <pending> }?

  1. 执行顺序错位:你同步调用了getMessageData(),这时候getNotifications()还没开始执行(或者还在等待fcmTokens()的异步结果返回),所以messageData还是初始的空对象{}。
  2. 异步赋值的延迟性:哪怕getNotifications()启动了,await fcmTokens()是异步操作,得等它完成后才会进入forEach给messageData赋值,而getMessageData()早就在这之前执行完了,自然拿不到赋值后的结果。
  3. 额外小问题:你的forEach里每次把messageData直接赋值为notificationData,最后messageData只会保留fcmObjects的最后一个元素,这大概率不是你想要的(如果想收集所有数据,应该用数组或者键值对形式存储)。

修正方案(推荐避免全局变量,用异步函数返回结果)

方案1:让getNotifications返回数据,在then中处理

去掉全局变量,让异步函数直接返回需要的数据,然后在它的then回调里调用处理逻辑:

const getNotifications = async () => {
  let fcmObjects = await fcmTokens();
  // 如果要收集所有数据,这里用数组示例(可根据需求改成对象)
  return fcmObjects;
};

function getMessageData(data) {
  console.log(data);
}

// 先执行异步函数,拿到结果后再调用处理函数
getNotifications()
  .then((messageData) => {
    getMessageData(messageData);
    console.log('All Done');
  })
  .catch((error) => {
    console.log('Oops', error);
  });

方案2:用async/await包裹执行逻辑(更直观)

如果你的执行环境支持顶级await(比如现代浏览器、Node.js 14.8+),可以这样写:

const getNotifications = async () => {
  let fcmObjects = await fcmTokens();
  return fcmObjects;
};

async function main() {
  try {
    const messageData = await getNotifications();
    console.log(messageData); // 直接在这里处理数据
    console.log('All Done');
  } catch (error) {
    console.log('Oops', error);
  }
}

main();

如果你一定要用全局变量(不推荐,易引发时序问题)

那必须确保在getNotifications执行完成后再调用getMessageData:

var messageData = []; // 改成数组存储所有数据,避免覆盖
const getNotifications = async () => {
  let fcmObjects = await fcmTokens();
  fcmObjects.forEach((notificationData) => {
    messageData.push(notificationData); // 用push添加,而非直接覆盖
  });
};

function getMessageData() {
  console.log(messageData);
}

// 等异步操作完成后再调用处理函数
getNotifications()
  .then(() => {
    getMessageData();
    console.log('All Done');
  })
  .catch((error) => {
    console.log('Oops', error);
  });

关键总结

  • 尽量避免用全局变量存储异步获取的数据,因为异步操作的时序很难控制,容易出现数据未就绪的情况。
  • 异步函数的结果最好通过return返回,然后用then或者await来获取,保证代码执行顺序符合预期。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.12 05:27:21