异步函数中向数组push元素后为空的问题及解决方法
问题原因
你用map遍历student.legalGuardians时,传入的是async函数,map会立即返回一个Promise数组,但不会等待这些异步操作执行完毕。外层的console.log(recipient)会在所有异步回调里的push操作之前运行,所以此时数组还是空的。
修复方案
用Promise.all等待所有异步操作完成,同时让每个异步函数返回要添加到数组的元素,最后将结果赋值给recipient:
// 外层需要包裹在async函数中 async function processGuardians() { let recipient = []; // 用map生成Promise数组,每个Promise返回要添加的元素(或undefined) const promises = student.legalGuardians.map(async (legalGuardians) => { let user = await getUserByNationalIdOrPhoneNumberOrEmail( legalGuardians.nationalId, legalGuardians.phoneNumber, legalGuardians.email ); if (!user || user === false) { return; // 过滤掉无效用户,返回undefined } let Notifystatus; if (user.firebaseToken != null && user.firebaseToken != undefined) { Notifystatus = await sendNotificationforUser( subject, body, data, user.firebaseToken ); } // 返回要添加的对象 return { userId: user._id, Notifystatus: Notifystatus, studentId: student._id, }; }); // 等待所有Promise完成,过滤掉undefined的项 recipient = (await Promise.all(promises)).filter(item => item !== undefined); console.log(recipient); // 此时数组已填充完成 } // 调用函数 processGuardians();
额外优化点
- 把
user.firebaseToken != null || user.firebaseToken != undefined改成user.firebaseToken != null && user.firebaseToken != undefined(或者更简洁的user.firebaseToken),因为原来的逻辑永远为true(只要token不是null或undefined其中一个,条件就成立,这不符合预期)。 - 避免在异步回调中修改外部变量(原代码的
recipient.push),改用返回值的方式,代码更清晰且不易出错。
内容的提问来源于stack exchange,提问作者ahmed basher
相关产品推荐
相关产品推荐

