Reputation: 610
I have a primary thread in my node application such as this:
function main_thread() {
console.log("Starting");
values = get_values(1);
console.log(values);
console.log("I expect to be after the values");
}
The get_values
function calls the hgetall
function using the node_redis package. This function provides a call back, but can be promisified:
function get_values(customer_id) {
// Uses a callback for result
new Promise(function(resolve, reject) {
redis_client.hgetall(customer_id, function (err, result) {
if (err) console.log(err)
console.log("About to resolve");
resolve(result);
});
})
.then(({result}) => {
console.log(result);
});
}
This works great for promise chaining within the function, however not so well in my main thread, as I can't wait and return the value.
Here's how I'd do it in ruby, the main language I use:
def get_values(customer_id)
return @redis_client.hgetall(customer_id)
end
How can I create a promise within a reusable function and make the main thread wait until the function returns the response from the promise?
EDIT:
It's been suggested the promise can be returned with a then
chained in the main thread. However this still means any code in the main thread after after the function call executes before the then
block.
EDIT 2:
After lengthy discussion with some IRL JS developer friends, it looks like trying to create a synchronous script is against the ethos of modern JS. I'm going to go back to my application design and work on making it async.
Upvotes: 3
Views: 7895
Reputation: 28573
Here is a working example with async
/await
. I've replaced the redis with a timeout and an array for the data.
async function main_thread() {
console.log("Starting");
values = await get_values(1);
console.log(`After await: ${values}`);
console.log("I expect to be after the values");
}
async function get_values(customer_id) {
return new Promise((resolve, reject) => {
setTimeout(() => {
const result = [1, 2, 3];
console.log(`Resolving: ${result}`);
resolve(result);
}, 300);
});
}
main_thread();
Further reading:
Upvotes: 3
Reputation: 8617
Simple as returning the promise (chain) from your function
function get_values(customer_id) {
// Uses a callback for result
return new Promise(function(resolve, reject) {
redis_client.hgetall(customer_id, function (err, result) {
if (err) console.log(err)
console.log("About to resolve");
resolve(result);
});
})
.then(({result}) => {
console.log(result);
});
}
And then in your main async function
or function
let result = await get_values();
or get_values.then(function(result){})
function main_thread() {
console.log("Starting");
values = get_values(1).then(function(values){
console.log(values);
console.log("I expect to be after the values");
});
}
async function main_thread() {
console.log("Starting");
let values = await get_values(1);
console.log(values);
console.log("I expect to be after the values");
}
Upvotes: 2
Reputation: 10009
Return the promise in get_values
function get_values(customer_id) {
// Uses a callback for result
return new Promise(function(resolve, reject) {
redis_client.hgetall(customer_id, function (err, result) {
if (err) console.log(err)
console.log("About to resolve");
resolve(result);
});
})
.then(({result}) => {
reject(result);
});
}
Now in your main thread, you could wait for it like:
function main_thread() {
console.log("Starting");
get_values(1).then(function(values) {
console.log(values);
}).catch(function(error) {
console.error(error);
});
}
Upvotes: 2