最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Waiting for promise to resolve from parent function - Stack Overflow

programmeradmin1浏览0评论

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.

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.

Share Improve this question edited Jun 7, 2019 at 23:53 Andrew White asked Jun 7, 2019 at 14:07 Andrew WhiteAndrew White 6101 gold badge11 silver badges29 bronze badges 3
  • And the same problem again with not returning a promise. Promise returns with 'undefined' or babel piled code doesn't wait for return (async/await) – crashmstr Commented Jun 7, 2019 at 14:12
  • Your main thread is NEVER going to wait for an asynchronous operation to plete. An individual function can wait with await, but that function still immediately returns a promise and the main thread continues. Javascript's main thread does not ever wait for asynchronous operations. See the other answers for how to use promises properly, but don't be thinking any of that will "pause" the entire main thread. It won't. – jfriend00 Commented Jun 7, 2019 at 14:13
  • You cannot make the main thread wait. You need to return a promise from get_values and then use promise chaining (or await) in the main_thread function. – Bergi Commented Jun 7, 2019 at 14:14
Add a ment  | 

3 Answers 3

Reset to default 3

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:

  • Using Promises
  • Promise Constructor

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);
  });
}

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");
}
发布评论

评论列表(0)

  1. 暂无评论