Reputation: 13588
I Am New To PROMISE.
I'm using nodejs promisify so I have the followings declared as promise for Redis
const { promisify } = require('util');
const getAsync = promisify(client.get).bind(client);
const hmsetAsync = promisify(client.hmset).bind(client);
const hsetAsync = promisify(client.hset).bind(client);
const incrAsync = promisify(client.incr).bind(client);
const smembersAsync = promisify(client.smembers).bind(client);
const keysAsync = promisify(client.keys).bind(client);
const sismemberAsync = promisify(client.sismember).bind(client);
I have the following function and I do not know where is the right place to put the resolve(message)
function sendMessage(senderId = '', roomId = '', text = '', type='text') {
var message = {}
return new Promise( function (resolve, reject) {
if (senderId == '') {
reject('Invalid Characters in Sender Id or Sender Id is empty.');
}
if (roomId == '') {
reject('Invalid Characters in Room Id or Room Id is empty.');
}
if (text == '') {
console.log('Text:' ,text);
reject('Invalid Characters in Text or Text is empty.');
}
//Check if Room Exist
keysAsync('room-'+roomId).then((value) => {
value == '' && reject('Room '+roomId+ ' does not exist.');
sismemberAsync('roomuser-'+roomId, senderId).then((ismember)=> {
ismember == 0 && reject('User ' + senderId + ' is not a member of room ' + roomId);
const datetime = new Date();
incrAsync('messageId')
.then((id) => {
//Create the message Hash
hmsetAsync('messsage:'+id, 'id', id, 'roomId', roomId, 'senderId', senderId, "created", datetime, "text", text);
//add message to Set
saddAsync('roommessages-'+roomId, id);
message = { id: id, roomId: roomId, senderId: senderId, created: datetime, text: text }
resolve(message) //If i place here i don't get the resolve.
}).catch(err => reject(err))
}).catch(err => reject(err))
}).catch(err => reject(err))
})
}
And then I tried to call the function like this
tools.sendMessage(3, 4, 'Does this work?','text').then((result)=> {
console.log('Send Message Result => ',result);
}).catch(err => {
console.log(err)
});
If I were to place the resolve(message) at where it is now, the above promise doesn't resolve, and "send Message result" doesn't show at all.
If i place it further out of the chain promise, the var message returns a empty object {}
My question: Where should I place the resolve in this kind of functions where I require multiple promise calls since I need to wait for multiple redis checks?
I have many functions that requires all my redis calls to be made before I can carry on to next action.
Upvotes: 0
Views: 241
Reputation: 26161
I might consider refactoring your code as follows. If you need to catch errors at interim .then()
stages then use onrejected callbacks.
function sendMessage(senderId = '', roomId = '', text = '', type='text') {
return keysAsync('room-'+roomId)
.then(value => value === '' ? Promise.reject('Room '+roomId+ ' does not exist.')
: sismemberAsync('roomuser-'+roomId, senderId))
.then(ismember => ismember === 0 ? Promise.reject('User ' + senderId + ' is not a member of room ' + roomId)
: incrAsync('messageId'))
.then(id => { var datetime =new Date();
hmsetAsync('messsage:'+id, 'id', id, 'roomId', roomId, 'senderId', senderId, "created", datetime, "text", text);
saddAsync('roommessages-'+roomId, id);
return { id: id, roomId: roomId, senderId: senderId, created: datetime, text: text };
})
.then(message => doSomethingWith(message))
.catch(errorHandler);
}
In the above code i moved the new Date()
to one stage below where it is actually used however if for some reason you need datetime
at the original .then()
stage as shown in your question then you may as well do as follows;
function sendMessage(senderId = '', roomId = '', text = '', type='text') {
return keysAsync('room-'+roomId)
.then(value => value === '' ? Promise.reject('Room '+roomId+ ' does not exist.')
: sismemberAsync('roomuser-'+roomId, senderId))
.then(ismember => ismember === 0 ? Promise.reject('User ' + senderId + ' is not a member of room ' + roomId)
: Promise.all([incrAsync('messageId'), new Date()]))
.then(([id, datetime]) => { hmsetAsync('messsage:'+id, 'id', id, 'roomId', roomId, 'senderId', senderId, "created", datetime, "text", text);
saddAsync('roommessages-'+roomId, id);
return { id: id, roomId: roomId, senderId: senderId, created: datetime, text: text };
})
.then(message => doSomethingWith(message))
.catch(errorHandler);
}
Upvotes: 1