如何确保父函数等待子函数获取数据后再返回有效结果?
问题根源
你这段代码本身都是同步执行的,不会出现“子函数没执行完就返回”的情况。真正的问题应该是调用buildLoadedData时,window.DATA还没有被赋值——比如window.DATA是通过异步脚本加载、AJAX请求获取的,此时它还处于未定义状态,导致getTagsByType拿到的是undefined,最终loaded_content为空。
解决办法
根据window.DATA的加载方式,选择对应的处理方案:
1. 监听数据加载完成事件
如果负责赋值window.DATA的脚本可以自定义事件,等数据准备好后触发事件,再调用buildLoadedData:
// 先监听数据加载完成的事件 window.addEventListener('dataReady', () => { const result = buildLoadedData(); // 在这里使用result }); // 赋值window.DATA的代码里,添加触发事件的逻辑: // window.DATA = { /* 你的数据内容 */ }; // window.dispatchEvent(new CustomEvent('dataReady'));
2. 异步轮询等待数据就绪
如果无法修改加载window.DATA的代码,可以把buildLoadedData改成异步函数,轮询检查数据是否存在:
export const getTagsByType = <Data extends { keywords?: { tags: { name: string, type: string }[] } }>(type: string, rawData: Data) => { return rawData.keywords?.tags.filter((tag) => tag.type === type).map(tag => tag.name); } export const buildLoadedData = async () => { // 轮询等待window.DATA存在 while (!window.DATA) { await new Promise(resolve => setTimeout(resolve, 100)); } // 加上可选链避免报错,空数组toString()会返回空字符串 return { "loaded_content": getTagsByType("generic", window.DATA)?.toString() || '' } } // 使用时需要用异步方式获取结果: // buildLoadedData().then(data => { // console.log(data.loaded_content); // });
3. 直接在数据加载的回调里调用
如果window.DATA是通过AJAX/fetch请求获取的,直接在请求成功的回调里执行buildLoadedData:
fetch('/api/get-data') .then(res => res.json()) .then(data => { window.DATA = data; const result = buildLoadedData(); // 使用result });
额外优化建议
原代码里如果rawData.keywords或tags不存在,getTagsByType会返回undefined,调用toString()会抛出错误。可以给getTagsByType加个默认返回值:
export const getTagsByType = <Data extends { keywords?: { tags: { name: string, type: string }[] } }>(type: string, rawData: Data) => { return rawData.keywords?.tags.filter((tag) => tag.type === type).map(tag => tag.name) || []; }
内容的提问来源于stack exchange,提问作者Elemental
相关产品推荐
相关产品推荐

