I've started to look at using Promises and have begun by putting together a simple function and calling it a few times. I need a sanity check around reject and resolve.
Anything I've got totally wrong?
const Redis = require('ioredis'); const redis = new Redis({ port: 6379, host: '127.0.0.1' }); function checkValues(name, section) { return new Promise((resolve, reject) => { redis.multi() .sismember('names', name) .sismember('sections', section) .exec() .then((results) => { if(results[0][1] === 1 && results [1][1] ===1) { reject('Match on both.'); } else if(results[0][1] === 1 || results [1][1] ===1) { reject('Match on one.'); } else { redis.multi() .sadd('names', name) .sadd('sections', section) .exec() .then((results) => { // Lazy assumption of success. resolve('Added as no matches.'); }) // No catch needed as this would be thrown up and caught? } }) .catch((error) => { console.log(error); }); }); } // Call stuff. checkValues('barry', 'green') .then((result) => { // Added as no matches "resolve" message from 'barry', 'green' console.log(result); retutn checkValues('steve', 'blue'); }) .then((result) => { // Added as no matches "resolve" message from 'steve', 'blue' retutn checkValues('steve', 'blue'); }) .then((result) => { // Match on both "reject" message from 'steve', 'blue' console.log(result); }) .catch((error) => { console.log(error); });
No, this is kind of an anti-pattern. You already have a function that returns a promise so you don't need to wrap it in another promise, you can just return it. Remember that then()
returns a promise that resolves to the return value of then
. You can also return another promise from then
. Usually this looks super clean, but in this case you need some logic in the then
function, so it gets a little messy.
function checkValues(name, section) {
// Just return this Promise
return redis.multi()
.sismember('names', name)
.sismember('sections', section)
.exec()
.then((results) => {
if(results[0][1] === 1 && results [1][1] ===1) {
// Rejections will be caught down the line
return Promise.reject('Match on both.');
} else if(results[0][1] === 1 || results [1][1] ===1) {
return Promise.reject('Match on one.');
} else {
// You can return another Promise from then()
return redis.multi()
.sadd('names', name)
.sadd('sections', section)
.exec()
}
})
// You don't need to catch here - you can catch everything at the end of the chain
}
Several points:
new Promise()
wrapper, change resolve
statements to return
and reject
statements to throw new Error(...)
. .catch()
catches! If errors are to be observable/handleable by the caller, then either don't catch in checkValues()
or catch and re-throw. Catching without re-throwing will cause the returned promise to settle on its success path, never its error path, which is great for error recovery but not always appropriate. return
rather than reject
/ throw
. That way, your call stuff chain will progress down its success path, .then().then().then()
, regardless of expected outcome; only an unexpected error will go down the error path to be caught by the final .catch()
. This isn't a general rule; very often, throwing is the right thing to do, but not here. function checkValues(name, section) {
return redis.multi()
.sismember('names', name)
.sismember('sections', section)
.exec()
.then((results) => {
if(results[0][1] === 1 && results [1][1] === 1) {
return 'Match on both.';
} else if(results[0][1] === 1 || results [1][1] ===1) {
return 'Match on one.';
} else {
return redis.multi()
.sadd('names', name)
.sadd('sections', section)
.exec()
.then((results) => {
return 'Added as no matches.';
});
}
})
.catch((error) => {
console.log(error);
throw error;
});
}
// Call stuff.
checkValues('barry', 'green')
.then((result) => {
console.log(result); // expect 'Added as no matches'
return checkValues('steve', 'blue');
})
.then((result) => {
return checkValues('steve', 'blue'); // expect 'Added as no matches'
})
.then((result) => {
console.log(result); // expect 'Match on both'
})
.catch((error) => {
// only an unexpected error will land here
console.log(error);
});
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.