0

I have a parent function that calls a child function.

The child function will execute its internal code asynchronously so I'd like the parent function to call the child and then continue its own execution without waiting.

function childFunc() {

  axios.post("http://api.example.com/user", { foo: "bar } ).
    then((response) => {

      // Do stuff here

      console.log("SUCCESS");
      return [1, 2, 3];

    }).
    catch((err) => {

      // Do stuff here

      console.log("ERROR");
      return [];

    });

  console.log("About to return null");

}

function parentFunc(url, data) { 

  // Call childFunc but then continue execution

  new Promise(function(resolve, reject) {

    let result = childFunc(url, data);
    result.length > 0 ? resolve(result) : reject("some error");

  });

  console.log("Continuing execution of `parentFunc()`");

  // Continue doing other stuff

}

I'm just learning about Promise and async behavior in JavaScript, so I'm confused about the following:

  1. What will childFunc return? If axios.post is executed asynchronously, wont the execution always continue past that and return null? Will the return statements inside then() or catch() ever fire? Does it return something twice?

  2. Will the logic in parentFunc do what I expect it to do here: call childFunc asynchronously while simultaneously moving forward with its own execution? I've seen the async/await syntax, but wasn't sure how that really worked and whether that could be used here somehow.

Thanks!

user2490003
  • 10,706
  • 17
  • 79
  • 155

1 Answers1

3

What will childFunc return? If axios.post is executed asynchronously, wont the execution always continue past that and return null? Will the return statements inside then() or catch() ever fire? Does it return something twice?

childFunc returns nothing or undefined right now, because you don't return anything from it.

Will the logic in parentFunc do what I expect it to do here: call childFunc asynchronously while simultaneously moving forward with its own execution? I've seen the async/await syntax, but wasn't sure how that really worked and whether that could be used here somehow.

Sort of.. You don't need to explicitly use a Promise, axios already uses the JS Promise API and exposes Promise objects you can pass around.

So really, your code would ideally look like this:

function childFunc() {

    return axios.post("http://api.example.com/user", { // childFunc now returns a Promise<Array<Number>>
        foo: "bar" } ).
      then((response) => {

            // Do stuff here

            console.log("SUCCESS");
            return [1, 2, 3];

        }).
        catch((err) => {

            // Do stuff here

            console.log("ERROR");
            return [];

        });

    // console.log("About to return null"); really would've been undefined, not null

}

function parentFunc(url, data) {

    // Call childFunc but then continue execution

    childFunc().then(results => {
        console.log("These are the results of the child function", results)
    // if you wanted to wait for childFunc to finish before continuing execution, put the statements to be executed after the childFunc execution here
    }).catch(err => {
        console.error("There was some error executing 'childFunc': " + err);
    })


    console.log("Continuing execution of `parentFunc()`");

    // Continue doing other stuff

}

EDIT:

Added example of rolling your own/creating our own Promise:

function longRunningCall() {
    return new Promise(function (resolve, reject) {
        try {

            setTimeout(function () {
                console.log("Done");
                resolve("done");
            }, 3000);
        } catch (error) { // this will never happen, but just to demonstrate handling errors asynchronously
            reject("error");
        }
    });
}

longRunningCall().then(function(result) {
    // the value of result will be "done";
}).catch(function(err) {
    // if there was an error, the value of err would be "error"
})
gabriel.hayes
  • 2,267
  • 12
  • 15
  • Thanks! I did not realize that `then()` returns another Promise (Im still very new to this). What about the situation where `childFunc` is in some other library that I don't have control over. I just know that it executes _something_ asynchronously and returns to me an array value. In that case should I still stick with my original approach of wrapping the `childFunc()` call in a Promise? – user2490003 Nov 11 '19 at 17:49
  • No, if it's a `Promise` object, you can handle it as a `Promise` object. `axios`, for example returns `Promise`s. You'd use `axios.post(someUrl).then` to handle the result of POSTing to `someUrl` with axios. No need to use additional Promises. You only need a Promise if you've got some long-running synchronous/deferred code for which you need to dynamically listen to completion of its execution (without blocking the thread of execution) – gabriel.hayes Nov 11 '19 at 17:51
  • 1
    Also yes, `Promise.then` returns a `Promise`. That's what allows you to go `axios.post(someUrl).then(/*handle success*/).catch(/*handle error*/)`. Fluent API is usually prettiest when dealing with recursion. Or you could register multiple handlers. `axios.post(someUrl).then(/*first task*/).then(/*second task*/)`, where whatever you return in the `then` callback is passed to the next `then` handler. – gabriel.hayes Nov 11 '19 at 17:53