我正在尝试在用户请求重置密码时发送短信。我想等待发送消息以提醒用户是否成功。我目前正在尝试如下:
async function sendResetPasswordTextMessage(req, res) {
let result = {};
let phoneNumber = req.body.phoneNumber;
if (phoneNumber === undefined) {
return sendInvalidParametersMessage(res);
}
phoneNumber = phoneNumber.toString();
const userProfile = await models.UserProfile.findOne({
where: {
phoneNumber: phoneNumber
}
});
************************** RELEVANT CODE TO ISSUE *************************
if (userProfile) {
const message = "Your username is:\n" + userProfile.username;
const sent = await AWSSNSClient.sendMessage(message, phoneNumber);
if (!sent) {
result.error = setTitleAndMessage("Error", "An error occurred");
} else {
result.success = setTitleAndMessage("Success", "Message sent");
}
}
return res.send(result);
***************************************************************************
}
在我的其他类AWSSNSClient中,我有以下sendMessage函数:
function sendMessage(message, phoneNumber) {
const params = {
Message: message,
MessageStructure: "string",
PhoneNumber: "+1" + phoneNumber
};
let sent = false;
sns.publish(params, function(err, data) {
if (err) {
console.log(err, err.stack); // an error occurred
}
else {
sent = true;
}
});
return sent;
}
我无法弄清楚如何使sendMessage等待sns.publish在返回之前返回。我试过把它变成异步方法并在sns.publish上添加await,但是在send发送设置为true之前函数仍会返回。
我知道邮件发送没有错误,因为我收到它们并且没有打印控制台日志。
答案 0 :(得分:9)
今天在Google上偶然发现了这个问题,试图自己解决-我现在正在使用的简短答案:
您现在可以使用Async / Await进行此操作—并使用扩展名.promise()调用AWS服务(例如SNS),以告诉aws-sdk使用该服务功能(SNS)的承诺版本。基于回调的版本。
这里唯一需要说明的是,包含函数必须还必须异步才能使用await语法。
例如:
let snsResult = await sns.publish({
Message: snsPayload,
MessageStructure: 'json',
TargetArn: endPointArn
}, async function (err, data) {
if (err) {
console.log("SNS Push Failed:");
console.log(err.stack);
return;
}
console.log('SNS push suceeded: ' + data);
return data;
}).promise();
重要的是最后的.promise()。有关以异步/基于承诺的方式使用aws-sdk的完整文档,请参见:https://docs.aws.amazon.com/sdk-for-javascript/v2/developer-guide/using-promises.html
要运行另一个aws-sdk任务,您可以类似地向该函数添加await和.promise()扩展名(假设可用)。 >
对于遇到此线程并实际上只是想将多个aws-sdk承诺推送到一个数组并等待该完整数组完成(不考虑哪个承诺首先执行)的任何人,我都会得到以下结果:
let snsPromises = [] // declare array to hold promises
let snsResult = await sns.publish({
Message: snsPayload,
MessageStructure: 'json',
TargetArn: endPointArn
}, async function (err, data) {
if (err) {
console.log("Search Push Failed:");
console.log(err.stack);
return;
}
console.log('Search push suceeded: ' + data);
return data;
}).promise();
snsPromises.push(snsResult)
await Promise.all(snsPromises)
希望能像我一样帮助通过Google偶然发现这一问题的人!
答案 1 :(得分:2)
stackdave会真正等待吗?
Necevil“成功执行的搜索推送将被记录两次”,因为您通过传递回调和使用Promise来混合调用操作。您应该只使用一种获取结果的方法
let snsResult = await sns.publish({
Message: snsPayload,
MessageStructure: 'json',
TargetArn: endPointArn}).promise()
会成功的
答案 2 :(得分:1)
你可以简单地使用回调。像这样修改你的sendMessge
function sendMessage(message, phoneNumber, cb) {
const params = {
Message: message,
MessageStructure: "string",
PhoneNumber: "+1" + phoneNumber
};
sns.publish(params, cb);
}
然后在您的主文件上,您可以像这样提供callback
if (userProfile) {
const message = "Your username is:\n" + userProfile.username;
AWSSNSClient.sendMessage(message, phoneNumber, (err, data) => {
if (err) {
result.error = setTitleAndMessage("Error", "An error occurred");
}
else {
result.success = setTitleAndMessage("Success", "Message sent");
}
res.send(result);
});
}
答案 3 :(得分:1)
这里是正确更新的API,2018年8月,Necevil回答两次发送短信。
// using config.env
AWS.config.region = 'eu-west-1';
AWS.config.update({
accessKeyId: process.env.AMAZON_SMS_ID,
secretAccessKey: process.env.AMAZON_SMS_TOKEN,
});
// parameters
let params = {
Message: contentSMS, // here your sms
PhoneNumber: mobile, // here the cellphone
};
const snsResult = await sns.publish(params, async (err, data) => {
if (err) {
console.log("ERROR", err.stack);
}
console.log('SNS ok: ' , JSON.stringify (data));
});
答案 4 :(得分:0)
如果您在发送重复的SNS消息时遇到问题,我通过利用AWS的示例解决了此问题:
// Load the AWS SDK for Node.js
var AWS = require('aws-sdk');
// Set region
AWS.config.update({region: 'REGION'});
// Create publish parameters
var params = {
Message: 'MESSAGE_TEXT', /* required */
TopicArn: 'TOPIC_ARN'
};
// Create promise and SNS service object
var publishTextPromise = new AWS.SNS({apiVersion: '2010-03-31'}).publish(params).promise();
// Handle promise's fulfilled/rejected states
publishTextPromise.then(
function(data) {
console.log("Message ${params.Message} send sent to the topic ${params.TopicArn}");
console.log("MessageID is " + data.MessageId);
}).catch(
function(err) {
console.error(err, err.stack);
});
通过使用传统的.then()
,我可以解决上面评论中提到的重复消息错误。
答案 5 :(得分:0)
你可以创建一个使用promise方法的异步函数
async function sendMessage(message, phoneNumber){
const params = {
Message: message,
PhoneNumber: phoneNumber
};
return new Promise((resolve, reject) => {
SNS.publish(params, (err, data) => {
if (err) {
console.log("Search Push Failed:");
console.log(err.stack);
return reject(err);
} else {
console.log('Search push suceeded:' + phoneNumber);
return resolve(data);
}
})
});
}
然后你可以打电话
var s= await sendMessage(message,phoneNumber);