异步迭代器获取实时日志异常:Promise已解析但值为undefined求助
问题分析与修复方案
你的代码存在三个核心问题,导致for await...of拿到undefined且无法正确等待Promise解析:
1. getNextLogEntry未返回数据
你的async函数没有返回API响应的JSON数据,默认会返回Promise<undefined>。必须显式返回解析后的数据,改用await语法更直观:
async function getNextLogEntry() { const postVars = new FormData; postVars.append('action', "40.6"); const options = { method: 'post', body: postVars, }; const response = await fetch('/admin/adminFuncs.php', options); const data = await response.json(); return data; // 必须返回解析后的JSON结果 }
2. 异步迭代器的next()方法不符合规范
异步迭代器的next()必须返回Promise<{value: any, done: boolean}>,但你当前的实现存在两个错误:
- 直接返回普通对象,未包裹成Promise
- 用未定义的
logLine变量判断终止条件,且未等待getNextLogEntry()的Promise完成
修复后的迭代器:
const END_OF_LOG = '---'; const asyncLogEntryIterable = { [Symbol.asyncIterator]() { return { async next() { // 先等待日志条目获取完成 const logEntry = await getNextLogEntry(); // 判断是否到达日志末尾 const done = logEntry.logLine === END_OF_LOG; const value = done ? undefined : logEntry; return { value, done }; }, return() { return Promise.resolve({ done: true }); // 异步迭代器的return建议返回Promise } } } };
3. 迭代终止逻辑需后端配合
必须确保Process A在完成所有认证步骤后,向MySQL内存表写入一条logLine为END_OF_LOG的条目,这样迭代器才能检测到终止信号并停止循环。
完整调用代码修正
修改后的循环可正确获取并处理日志,同时修复了样式代码的小错误:
if (event.target.id === 'testAuthenticationButton') { submitAuthenticationTest().finally(); testAuthenticationDiv.style.display = 'none'; const authenticationLog = document.getElementById('authenticationLog'); authenticationLog.style.display = 'block'; authenticationLog.style.border = '1px solid black'; // 原代码borderStyle写法错误 (async () => { try { for await (const x of asyncLogEntryIterable) { console.log(x.logLine); // 追加日志到页面 authenticationLog.textContent += x.logLine + '\n'; } } catch (err) { console.error('获取日志出错:', err); } })(); }
关键概念补充
- 异步迭代器的
next()必须返回Promise,for await...of会自动等待Promise解析后再进入下一次循环 async函数若无显式return,默认返回Promise<undefined>,这是你拿到undefined的核心原因- 迭代终止依赖后端返回的结束标记,需确保Process A在任务完成后写入该标记
内容的提问来源于stack exchange,提问作者Yehuda
相关产品推荐
相关产品推荐

