Why does this work?

Bruce Gust
Bruce Gust used Ask the Experts™
on
Here's my code:

exports.deletePost = (req, res, next) => {
  const postId = req.params.postId;
  Post.findById(postId)
    .then(post => {
      if (!post) {
        const error = new Error("Could not find post.");
        error.statusCode = 404;
        throw error;
      }
      //check login user
      clearImage(post.imageUrl);
      return Post.findByIdAndRemove(postId);
    })
    .then(result => {
      console.log(result);
      res.status(200).json({ message: "Deleted post!" });
    })
    .catch(err => {
      if (!err.statusCode) {
        err.statusCode = 500;
      }
      next(err);
    });
};

Open in new window


Line #12, it says return Post.findByIdAndRemove(postId).

I was always under the impression that once you invoke the "return" dynamic, you're exiting the flow of the code at that point. Yet, in this case, it proceeds to the next "then" clause.

Why?

The code works, but I want to know why the continues to the next "then" clause despite the fact that there's a "return" dynamic in place.
Comment
Watch Question

Do more with

Expert Office
EXPERT OFFICE® is a registered trademark of EXPERTS EXCHANGE®
leakim971Multitechnician
Top Expert 2014

Commented:
this is promise : https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise

the question is : how do we send something to the next "executor" parameter
the answer is : use return

something : Post.findByIdAndRemove(postId)
next "executor" parameter : result
Bruce GustPHP Developer

Author

Commented:
So, my confusion, then, stems from the fact that I'm looking at "return" in the context of a conventional function as opposed to the way it's being used her in the context of a callback / promise, yes?
Most Valuable Expert 2018
Distinguished Expert 2018
Commented:
Hey Bruce,

You still looking at it in the correct context, but the bit I think you're missing is that you're actually chaining anonymous functions together. Your return statement does exit the flow of the function it's contained in. Instead of using anonymous function, think of it more like this::

function DeletePost(post) {
      if (!post) {
        const error = new Error("Could not find post.");
        error.statusCode = 404;
        throw error;
      }
      //check login user
      clearImage(post.imageUrl);
      return Post.findByIdAndRemove(postId);
}

Open in new window

If you expand out your anonymous functions to full functions, it might be a little clearer:

Post.findById(postId)
    .then(DeletePost)
    .then(OutputTheResult)
    .catch(ErrorHandler);



function DeletePost(post) {
    // the findById returns a Post (by resolving a promise)
    // that gets passed into this function which we can use in here
    // and we can also return something from this function which will be passed into the next
    if (!post) {
        const error = new Error("Could not find post.");
        error.statusCode = 404;
        throw error;
    }
    //check login user
    clearImage(post.imageUrl);
    return Post.findByIdAndRemove(postId);
}

function OutputTheResult(result) {
    // result is what gets returned from the previous function
    console.log(result);
    res.status(200).json({ message: "Deleted post!" });
}

function ErrorHandler(err) {
    // Oops - Something went wrong!

}

Open in new window

Bruce GustPHP Developer

Author

Commented:
I get it! So the "return" is not functioning any differently than it normally does in that it still a "disruption." But because it's happening in the context of several functions chained together, the "disruption" is routed to the next link in the chain as opposed to it forcing the trajectory of the code outside the method as a whole.

Correct?
Most Valuable Expert 2018
Distinguished Expert 2018
Commented:
Yep - that's pretty much it. Your return is still just returning a value from a function. It's just that when you chain your functions together like that, the value returned is just automatically passed as a parameter into the next function. Take a look a this:

var myResult = DoSomething();
var nextResult = AnotherFunction( myResult );
var lastResult = FinalFunction( nextResult );
console.log( lastResult );

Open in new window

All we're doing here is manually assigning the return value of a function to variable. We're then passing that variable into another function, and so on and so on :)

The reason we chain like this using promises is because when we call an Async function, we never know when that function will complete (it might take a millisecond / it might take 10 seconds), but it does promise to return at some point. With a promise, you then call the next function, passing in the result of previous call.
Bruce GustPHP Developer

Author

Commented:
Thank you!

Do more with

Expert Office
Submit tech questions to Ask the Experts™ at any time to receive solutions, advice, and new ideas from leading industry professionals.

Start 7-Day Free Trial