递归Async函数未返回值,如何排查问题?
问题排查与修复方案
让我帮你找出代码里的问题——核心原因是递归调用时没有传递返回值,导致最外层的await拿不到最终的'DONE'结果。
问题分析
看你的processQueue函数:当this.#size不等于0时,你递归调用了await this.processQueue(),但这里没有把递归调用的结果return出去。也就是说:
- 只有最后一次递归(当
#size==0时)会返回'DONE' - 但上层的递归函数并没有把这个值传递回更上层
- 最终最外层的
await myHandler.processQueue()拿到的是undefined,而不是预期的'DONE'
排查思路
你可以用这些方法定位问题:
- 在递归调用的else分支里加日志,查看递归调用的返回值:
else { console.log('... next ...'); const recursiveResult = await this.processQueue(); console.log('Recursive result:', recursiveResult); // 这里会发现recursiveResult是'DONE',但没返回给上层 } - 用浏览器调试器或Node.js调试工具,给
return 'DONE'和else分支的递归处加断点,跟踪返回值的传递路径,就能发现上层函数没有把递归结果返回。
修复代码
只需要在else分支的递归调用前加上return,把下层的返回值传递回上层:
let sleep = function(ms) { return new Promise (function(resolve, reject) { setTimeout(function(){ console.log('[DELAYED_PROCESS] completed.'); resolve('data_stream'); }, ms); }); } class RequestHandler { #isBusy = false; #size = 9; constructor(name=null) { this.name = name == null ? 'handler_' + Math.floor(Math.random() * 10000) : 'handler_' + name; this.id = Math.floor(Math.random() * 10000); console.log(`created handler with NAME: ${this.name} and ID: ${this.id}`); } async processQueue() { this.#isBusy = true; console.log(this.#size); try{ let task = await sleep(2000); console.log(`Data received. ${this.#size}`); }catch(e){ console.log(`Data failed. ${this.#size}`); console.log('continue ...'); } // Reduce Size this.#size -= 1; // Queue is consumed, we are done. if (this.#size==0) { console.log('... done ...'); this.#isBusy = false; return 'DONE'; } else { console.log('... next ...'); // 关键:返回递归调用的结果,让值传递回上层 return await this.processQueue(); } }; } const myHandler = new RequestHandler('banana'); console.log('[1] This task relies on the response being received ... (working)'); (async () => { let response = await myHandler.processQueue() console.log(`[1] result: ${response}`); // 现在会打印"[1] result: DONE" console.log('[1] Done.'); })(); console.log('[2] Some other task running.'); console.log('[2] Some other task is done.');
修改后,每次递归调用都会把下层的返回值传递回上层,最终最外层的await就能拿到'DONE'了。
内容的提问来源于stack exchange,提问作者mbilyanov
相关产品推荐
相关产品推荐

