JavaScript递归async函数返回undefined问题排查
JS异步递归生成唯一人员缩写返回值异常修复
功能规则
编写的generateShort函数用于接收人员的名(firstName)和姓(lastName),生成唯一人员缩写,生成规则为:取姓的前2位+名的前2位转小写后,拼接从1开始递增的数字后缀,保证缩写唯一,示例:
Michael Scott -> scmi1
Michelle Scrambledeggs -> scmi2
Genghis Khan -> khge1
问题原因
嵌套的递归函数findFreeSuffix执行时console.log能打印正确后缀,但外层await拿到的值始终为undefined,是两个异步写法错误导致的:
return suffix_number写在了.then()的回调函数内部,这个返回值只会作为Promise回调的执行结果,不会被外层的findFreeSuffix函数返回- 递归调用
findFreeSuffix(suffix_number + 1)时没有加return,内层递归找到的可用后缀无法逐层透传到最外层调用处
修复后代码
统一使用async/await写法处理异步逻辑,同时给递归调用添加return保证返回值传递:
/** * 根据用户姓名生成唯一缩写 * 规则:姓前2位 + 名前2位 + 不重复数字后缀 * @param {string} firstName 名 * @param {string} lastName 姓 * @returns {string} 唯一缩写,例:John Smith -> smjo1 */ const generateShort = async (firstName, lastName) => { // 拼接姓名前缀并转小写 const short = (lastName.substring(0, 2) + firstName.substring(0, 2)).toLowerCase() // 递归查找未被占用的数字后缀 async function findFreeSuffix(suffix_number) { const final_short = short + suffix_number // 查询数据库中是否已存在该缩写 const res = await window.api.searchClientExact(final_short) if (res.length > 0) { // 后缀已占用,数字+1继续查找,必须加return透传递归结果 return findFreeSuffix(suffix_number + 1) } else { // 找到可用后缀,返回 return suffix_number } } const suffix = await findFreeSuffix(1) return short + suffix }
注意点
- 同一段异步逻辑中尽量不要混用
.then()链式调用和async/await,很容易出现返回值丢失、异常无法捕获的问题 - 异步递归场景下,每一层的递归调用结果都必须显式return,否则最外层无法拿到内层的执行结果
- 原代码中使用
var声明变量存在变量提升风险,建议替换为let/const
内容的提问来源于stack exchange,提问作者gandalf113
相关产品推荐
相关产品推荐

