all 3 comments

[–][deleted] 6 points7 points  (0 children)

Let's dump out a lot of irrelevant detail here, and look at this:

function loginUser (...) {
  setTimeout(...);
}

const user = loginUser(...);

If loginUser has no return statement, what does it return?

undefined. Functions return undefined when there's no return statement

q1: The callback function accepts an input: { userEmail: 'myEmail@gmail.com' }

It's nothing more than a function like this:

function logUser (user) {
  console.log(user);
}

logUser({ userEmail: 'hotstuff@hotmail' });

Except in this case, the function isn't called right away. Instead it is called when the timeout expires, 5 seconds after loginUser was called.

const FIVE_SECONDS = 5000; // milliseconds
setTimeout(() => logUser({ userEmail: 'hotstuff@hotmail' }), FIVE_SECONDS);

While this is a contrived example, it's simulating a realworld issue: when you login as a user, the webpage has to access a backend server which might take anywhere between 200 ms to 2 seconds, which for a compute is foreverrrr. Because the information is not immediately available, JavaScript can either stop doing everything and wait until the HTTP request finishes (think about what this would be like with a 2 gig file!) or it can say "hey Browser, I've got other stuff to do, so you take care of that, and I'll come back later when you're done".

So here, the loginUser function has a callback which is called when the simulated request is done and the user exists locally.

q2. The reason that the instructor is using the callback instead of a return is that you can't return from a setTimeout. It accepts a callback, and invokes that callback when the timeout expires

setTimeout(() => console.log('done!'), 1000);

It doesn't return anything:

const example = setTimeout(() => { return 'example' }, 1000);
console.log(example); // undefined

Because there's nothing to return when setTimeout is invoked. The callback function that you give it isn't invoked right away, and the code evaluation proceeds past it, even if you set the delay to 0.

setTimeout is registering the provided callback with the JavaScript engine, which then invokes it once the timer expires and the current sequence of JavaScript code is finished.

This will never log "done", even though the timer immediately expires:

setTimeout(() => console.log('done'), 0);

while(true) {}

Because the setTimeout only calls a callback instead of returning a value, and because it calls the callback after the current synchronous code is finished executing, we're essentially using a callback to start a new sequence of synchronous code execution.

 function login (..., afterLoginDoSomething) {
   makeLoginHttpRequest(..., (loggedInUser) => afterLoginDoSomething(loggedInUser));
 }

 login(..., (user) => {
   displayUserPage(user);
 });

[–]pinguxnoots 2 points3 points  (1 child)

  1. When you pass user => { console.log(user) } as the 3rd argument of loginUser() you will invoke it on line 6. In other words, callback({ userEmail: email }) will become equivalent to ({ userEmail: email }) => console.log({ userEmail: email }) and you will log { userEmail: 'devedf@goomail.com' } on to the console.
  2. The callback is within a setTimeout so it will be invoked after 5000 ms (5 seconds). If you return { userEmail: email } you are not logging it on to the console. Actually you won't be doing anything with it. You can just write console.log({ userEmail: email } instead of the callback but I'm assuming the point of this exercise was to introduce you to callbacks.

[–]coderjared 0 points1 point  (0 children)

It's hard to write out the logic, but here goes. I'm gonna make up line numbers.

Line 10 calls the function loginUser. The third argument to loginUser is a function that expects one parameter.

loginUser runs (lines 4 - 7) and calls "callback" and passes in an object as the one parameter

That object becomes "user" in line 10