JavaScript Async/Await结合.map异步操作返回值异常问题
问题:async/await处理数组请求时返回undefined且未等待Promise解析
我尝试用async和await构建函数,遍历对象数组,为每个对象发起外部axios请求,获取响应后更新对象,最终返回更新后的对象数组。目前遇到的问题:输出未等待Promise解析,数组被推入undefined值,且数组在处理对象前就被打印。
原代码
构建对象的函数
const createHRObj = async function (workflow) { if (workflow.type_of_leave === "Personal") { getAbsenceDetail( `${workflow.employeeID}`, `${workflow.startDate}`, `${workflow.endDate}` ).then((res) => { try { console.log(`------- Handling Personal Leave! ----------`); console.log(workflow); if (res.Status != 0) throw new Error(`PeopleHR absence status code: ${res.Status}`); let absences = res.Result; if (absences.length === 0) workflow.on_PeopleHR = false; if (absences.length > 0) { let count = 0; absences.forEach((absence) => { if ( Date.parse(absence.StartDate) <= Date.parse(workflow.startDate) && Date.parse(absence.EndDate) >= Date.parse(workflow.endDate) ) count++; }); count > 0 ? (workflow.on_PeopleHR = true) : (workflow.on_PeopleHR = false); } console.log(`------- Absence Workflow Output! ----------`); console.log(workflow); console.log( `------- Updating and returning workflow! ----------` ); return workflow; } catch (err) { console.log(err); } }); } else { getHolidayDetail( `${workflow.employeeID}`, `${workflow.startDate}`, `${workflow.endDate}` ).then((res) => { try { console.log(`------- Handling Business Leave! ----------`); console.log(workflow); if (res.data.Status != 10) throw new Error( `PeopleHR holiday status code: ${res.data.Status}` ); let holidays = res.data.Result; if (holidays.length === 0) workflow.on_PeopleHR = false; if (holidays.length > 0) { let count = 0; holidays.forEach((holiday) => { if ( Date.parse(holiday.StartDate) <= Date.parse(workflow.startDate) && Date.parse(holiday.EndDate) >= Date.parse(workflow.endDate) ) count++; }); count > 0 ? (workflow.on_PeopleHR = true) : (workflow.on_PeopleHR = false); } console.log(`------- Absence Workflow Output! ----------`); console.log(workflow); console.log( `------- Updating and returning workflow! ----------` ); return workflow; } catch (err) { console.log(err); } }); } };
调用函数
const peopleHR_Check = async function (workflows) { console.log(`----- We're now inside the PeopleHR Checker -------`); Promise.all( workflows.map(async (workflow) => { let outputObj = await createHRObj(workflow) return outputObj }) ) .then(res => console.log(res)) };
错误原因分析
createHRObj未返回有效Promise:虽然标记了async,但内部使用.then()处理请求,且没有将这个Promise返回。async函数默认返回resolve(undefined)的Promise,导致await createHRObj(workflow)得到undefined。- 混用async/await与.then():回调式的
.then()打破了async/await的同步化流程,使得函数无法正确等待请求完成就返回了默认的undefined。 - 错误处理范围不当:try/catch被包裹在
.then()回调内,无法捕捉请求本身的错误,且错误发生后没有返回合理的 fallback 值。
修复后的代码
修复createHRObj函数
const createHRObj = async function (workflow) { try { if (workflow.type_of_leave === "Personal") { console.log(`------- Handling Personal Leave! ----------`); console.log(workflow); const res = await getAbsenceDetail( `${workflow.employeeID}`, `${workflow.startDate}`, `${workflow.endDate}` ); if (res.Status != 0) throw new Error(`PeopleHR absence status code: ${res.Status}`); const absences = res.Result; workflow.on_PeopleHR = absences.some(absence => Date.parse(absence.StartDate) <= Date.parse(workflow.startDate) && Date.parse(absence.EndDate) >= Date.parse(workflow.endDate) ); } else { console.log(`------- Handling Business Leave! ----------`); console.log(workflow); const res = await getHolidayDetail( `${workflow.employeeID}`, `${workflow.startDate}`, `${workflow.endDate}` ); if (res.data.Status != 10) throw new Error(`PeopleHR holiday status code: ${res.data.Status}`); const holidays = res.data.Result; workflow.on_PeopleHR = holidays.some(holiday => Date.parse(holiday.StartDate) <= Date.parse(workflow.startDate) && Date.parse(holiday.EndDate) >= Date.parse(workflow.endDate) ); } console.log(`------- Absence Workflow Output! ----------`); console.log(workflow); console.log(`------- Updating and returning workflow! ----------`); return workflow; } catch (err) { console.error(err); // 错误时返回原workflow或设置默认值,避免Promise被拒绝导致Promise.all失败 workflow.on_PeopleHR = false; return workflow; } };
修复peopleHR_Check函数
const peopleHR_Check = async function (workflows) { console.log(`----- We're now inside the PeopleHR Checker -------`); try { const updatedWorkflows = await Promise.all( workflows.map(workflow => createHRObj(workflow)) ); console.log(updatedWorkflows); return updatedWorkflows; } catch (err) { console.error('批量处理失败:', err); } };
修复关键点
- 用await替代.then():在async函数内使用await等待请求完成,确保代码按预期顺序执行,同时自然返回处理后的结果。
- 统一错误处理:将try/catch提升到外层,捕捉请求和业务逻辑中的所有错误,避免Promise静默拒绝导致
Promise.all整体失败。 - 简化逻辑:用
Array.some()替代forEach计数,更简洁高效地判断是否存在符合条件的记录。 - 确保返回值:无论成功或失败,都返回处理后的workflow,保证
Promise.all能拿到完整的结果数组。
内容的提问来源于stack exchange,提问作者joshsutheran
相关产品推荐
相关产品推荐

