在移动到另一个迭代之前等待内部循环



我正在尝试使用函数通过API发送消息。当函数履行职责时,它会返回一个messageLodId的值,并且需要在主循环中Attendence更新。但是当我执行此代码时,值是未定义的。

有两个问题:

1(结构是否正确?

2(如果是,请提供此问题的答案。

//Posting SMS 
router.post('/sms/', async function(req, res) {
let attendenceRecordId = parseInt(req.body.attendenceRecordId);
let result = await AttendenceRecord.findOne({where: {id: attendenceRecordId }, include: [ {model: Attendence, include: [{model: Student}
]}, {
model: Class
}], order: [['date', 'DESC']]});
if(!result) {
res.sendStatus(404); 
}
for await (let attendence of result.attendences){
let messageLogId = await sendSMS(attendence); 
console.log("Message ID: ", messageLogId); 
Attendence.update(
{ smsLogId: messageLogId },
{ where: { id: attendence.id  } }
); 
}
AttendenceRecord.update(
{ isMessageSent:true },
{ where: { id: result.id } }
); 
res.send({messageSent: true});
});

下面是函数定义。现在我只是返回 1。

在现实世界中,URL 返回一个代码。

async function sendSMS(attendence){
//console.log(target);

setTimeout(function(){
let message = `Respected Parent, your son/daughter ${attendence.student.name} is absent on ${attendence.date}`;
let messageURL = encodeURI(message); 
let api = 'SOME VALUE';
let phone = attendence.student.fphone.substring(1, 11); 
let target = `http://BASE_URL/api.php?key=${api}&receiver=92${phone}&sender=DigitalPGS&msgdata=${messageURL}`; 
return 1; 
}, 2000); 

}

你应该从发送短信中返回承诺。解决 setTimeout 回调函数中的承诺。

function sendSMS(attendence){
//console.log(target);
return new Promise((resolve, reject) => {
setTimeout(function(){
let message = `Respected Parent, your son/daughter ${attendence.student.name} is absent on ${attendence.date}`;
let messageURL = encodeURI(message); 
let api = 'SOME VALUE';
let phone = attendence.student.fphone.substring(1, 11); 
let target = `http://BASE_URL/api.php?key=${api}&receiver=92${phone}&sender=DigitalPGS&msgdata=${messageURL}`; 
resolve(1); 
}, 2000); 
});
}

你应该sendSMS返回一个承诺,并等待:

exec();
async function exec()
{
var records = [1,2,3];
for(var i=0;i<records.length;i++)
{
var messageLogId = await sendSMS(records[i]);
console.log("Result received from resolve", messageLogId);
}
}
function sendSMS(record)
{
// simulate an async method:
return new Promise(function(resolve, reject) {
setTimeout(function() {
console.log("Send sms for record", record);
resolve(1);
}, 1000);
});
}

请注意,此处setTimeout只是演示异步操作。在现实世界中,您的sendSMS函数无疑会调用一个 API,而 API 本身将是异步的 - 只需从中返回承诺(或者,如果 API 客户端不返回一个,则将调用包装在承诺中(。

首先,让你的函数Promisify.然后对函数进行分块并在for循环中调用该函数,并使用Promise.all()进行处理。

const manyPromises = [];
for (const attendence of result.attendences) {
manyPromises.push(sendSmsAndUpdateStatus(attendence));
}
// Execution wait until all promises fulfilled/rejected
const result = await Promise.all(manyPromises);
const sendSmsAndUpdateStatus = async (attendence) => {
try {
const messageLogId = await sendSMS(attendence);
const updateObj = { smsLogId: messageLogId };
const condition = { where: { id: attendence.id } };
const result = await Attendence.update(updateObj, condition);
return { result, messageLogId };
} catch (err) {
logger.error(err);
throw err;
}
};
const sendSMS = (attendence) => {
return new Promise((resolve) => {
setTimeout(() => {
const message = `Respected Parent, your son/daughter ${attendence.student.name} is absent on ${attendence.date}`;
const messageURL = encodeURI(message);
const api = 'SOME VALUE';
const phone = attendence.student.fphone.substring(1, 11);
const target = `http://BASE_URL/api.php?key=${api}&receiver=92${phone}&sender=DigitalPGS&msgdata=${messageURL}`;
return resolve(1);
}, 2000);
});
};

总结确保你的函数sendSMS将返回Promise,之后你可以用async/await.then().catch()的方法来处理它。

最新更新