如何正确处理Promise?递归异步函数未完成问题排查
问题排查与修复
1. 语法错误导致Promise链中断
getAllRecords函数中存在语法错误,直接导致函数执行报错、Promise无法正常解析:
// 错误代码:缺少闭合右括号 if (responseData.length === 0 {
修复后:
if (responseData.length === 0) {
2. 逻辑判断错误导致流程异常
mainFunc中Promise.allSettled的回调逻辑有误,错误的布尔值比较会导致结果判断颠倒:
// 错误代码:!errorArr.length是布尔值,与0比较逻辑不符合预期 if (!errorArr.length > 0) {
修复后:
if (errorArr.length === 0) {
3. Promise嵌套反模式引发的混乱
mainFunc本身是async函数,却手动包裹new Promise属于冗余嵌套,容易导致Promise链处理混乱;同时then回调中使用async函数,可能造成内部Promise未被正确串联。
4. getAllRecords递归逻辑验证
修复语法错误后,getAllRecords的递归逻辑是正确的:每次获取数据并处理完成后,才会递归调用下一页,直到返回空数据时返回成功状态,Promise链会正确等待所有递归步骤完成。
仅用Promise实现的版本(移除async/await)
async/await是Promise的语法糖,完全可以通过纯Promise链式调用实现相同逻辑:
修复后的getAllRecords(纯Promise版)
const getAllRecords = (offset = 0) => { return fetchRecord(offset, 10).then((resp) => { console.log("Called fetchRecord") if (resp.status === 'success') { let responseData = resp.data if (responseData.length === 0) { return { status: 'success' } } return processData(responseData).then((updateResp) => { if (updateResp.status === 'success') { offset += 10 return getAllRecords(offset) } else { return { status: 'error' } } }).catch(err => { return { status: 'error' } }) } else { return { status: 'error' } } }).catch(err => { return { status: 'error' } }) }
修复后的mainFunc(纯Promise版,移除冗余嵌套)
const mainFunc = () => { console.log('Inside mainFunc') return firestore.getAllCities() .then((cities) => { return getAllRecords().then(getAllRecordsResponse => { console.log("Called getAllRecords") if (getAllRecordsResponse.status !== 'success') { throw { status: 'error' } } return cities }) }) .then((cities) => { let updateArray = [] console.log("Updating firestore db") for (const city of cities) { updateArray.push(firebaseDao.updatecityDoc(city)) } return Promise.allSettled(updateArray) }) .then((responseArr) => { let errorArr = [] responseArr.forEach((item) => { if (item.status === 'rejected') { errorArr.push(item.reason) } }) if (errorArr.length === 0) { console.log("done processing") return { status: 'success' } } else { return { status: 'error' } } }) .catch((err) => { return { status: 'error' } }) }
关键说明
- 修复语法错误后,
getAllRecords的递归Promise链会正确等待所有分页数据的获取与处理,不会出现未完成的情况。 - 纯Promise版本通过
then和catch链式调用实现流程控制,与async/await逻辑完全等价,仅写法不同。 - 避免在
async函数中手动创建new Promise,直接返回Promise链可简化逻辑、降低出错概率。
内容的提问来源于stack exchange,提问作者Renee
相关产品推荐
相关产品推荐

