In below Node.js function, how do I return data.QueueUrl, so that a caller can get the value with
var url = await createSubscription('foo', req);
This is the function
async function createSubscription(name, req){
var params = {
QueueName: name,
Attributes: {
'ReceiveMessageWaitTimeSeconds': '20', // long polling wait time
}
};
sqs.createQueue(params, function(err, data) {
if (err) {
logger.error("createQueue error : " err, req);
} else {
logger.log("queue " name ' created', req);
return data.QueueUrl;
}
});
}
CodePudding user response:
You could make your function to return a Promise and resolve and reject the required data according to your logic. The other way is to promisfy your callback using the util module.
CodePudding user response:
Write your function like this to return a promise
async function createSubscription(name, req){
try{
const params = {
QueueName: name,
Attributes: {
'ReceiveMessageWaitTimeSeconds': '20', // long polling wait time
}
};
let data = await sqs.createQueue(params).promise();
return data;
}
catch(err){
logger.error("createQueue error : " err.message);
}
}
And call it like this to receive the value
const url = await createSubscription('foo', req);
console.log(url.QueueUrl); // You'll get the result in url variable.
CodePudding user response:
The function doesn't need to be async
to create and return a promise:
function createSubscription (name, req) {
return new Promise((resolve, reject) => {
const params = {
QueueName: name,
Attributes: {'ReceiveMessageWaitTimeSeconds': '20'}
};
sqs.createQueue(params, (err, data) => {
if (err) {
logger.error('createQueue error : ' err, req);
reject(err);
} else {
logger.log('queue ' name ' created', req);
resolve(data.QueueUrl);
}
});
});
}
const url = await createSubscription('foo', req);
CodePudding user response:
Best practice is to wrap problematic functions at the lowest possible level, and then never call them directly again - MDN
For you this means doing the following:
function createQueue(params) {
return new Promise((resolve, reject) => {
sqs.createQueue(params, (err, data) => err ? reject(err) : resolve(data));
});
}
After that you can work with createQueue
instead of sqs.createQueue
:
async function createSubscription(name, req) {
const params = {
QueueName: name,
Attributes: {
'ReceiveMessageWaitTimeSeconds': '20', // long polling wait time
}
};
try {
const data = await createQueue(params);
logger.log("queue " name ' created', req);
return data.QueueUrl;
} catch (err) {
logger.error("createQueue error : " err, req);
// you'll probably want to re-throw here unless the caller knows
// that an undefined return value means an error has occurred
}
}
Without all the additional log statements, the function can also look like this:
async function createSubscription(name, req) {
const params = {
QueueName: name,
Attributes: {
'ReceiveMessageWaitTimeSeconds': '20', // long polling wait time
}
};
const data = await createQueue(params);
return data.QueueUrl;
}
Since we don't use a try/catch the error/rejected promise bubbles up to the caller.
Since all the SQS functions are in the style sqs.function(params, callback)
(see documentation), you could also write a more general helper that works on all the SQS functions.
function sqsPromise(sqsFnName, params) {
return new Promise((resolve, reject) => {
sqs[sqsFnName](params, (err, data) => err ? reject(err) : resolve(data));
});
}
Which allows you to do:
const data = await sqsPromise("createQueue", params);