-1

Does line 17 return return from the blue or red scope?

enter image description here

isherwood
  • 58,414
  • 16
  • 114
  • 157
TheThing
  • 21
  • 7
  • `isAuthenticated()` is an asynch call, when it executes it will return `true` which will then get returned from the function. – Nicholas K Apr 10 '20 at 19:31

2 Answers2

2

This has nothing to do with promises. A return statement always returns from the innermost function that it is located in.

However, the magic of promises is that the return value of the then callback becomes the resolution value of the outer promise, which is the one you are returning from the outer function.

Bergi
  • 630,263
  • 148
  • 957
  • 1,375
  • let me get this straight, `.then()`'s callback is fired after `isAuthenticated()` resolves the promise's value (which gets passed to `authenticated` argument). So if i didn't call `.then()` and return `true`, my promise still wouldn't contain the value I `resolve()`'d in the callback fired when creating the promise initially? – TheThing Apr 10 '20 at 19:37
  • -- Also, do we return a promise with an undefined value before `.then()` is asynchronously called? If I wanted to use this promise in the function that called `canActivate()`, would i need to perform some null check to ensure `.then()` has completed? Is `.then()` even called asynchronously? – TheThing Apr 10 '20 at 19:40
  • I promise to pay you one million US dollars. How much money (of mine) do you have right now? None, because the promise has not been fulfilled (and never will be, trust me :)). You can attach a `then` to that promise (then, you'll buy a Ferrari), but you can't actually do that until you get that million dollars (well, I don't know your credit rating, but let's not digress). "Promise" was one of the great names made in software, in my opinion, because it captures what is happening. @TheThing – Heretic Monkey Apr 10 '20 at 19:51
  • @TheThing "*then()'s callback is fired after isAuthenticated() resolves the promise*" - yes. "*Do we return a promise with an undefined value before .then() is asynchronously called?*" - no, we return an *unresolved* promise that will later be fulfilled or rejected. And `.then()` itself is called synchronously, to create that promise, it is the callback that you are passing that is always called asynchronously. – Bergi Apr 10 '20 at 19:54
  • @HereticMonkey thanks. My confusion is whether we can/should handle the promise outside of the `.then()` block, since we technically could be returning it to a calling function. Mostly use-case oriented – TheThing Apr 10 '20 at 19:55
  • @TheThing Yes, you should in general always return the promise to your caller (so that they at least can wait until you're done, or even better use your result value), and yes, the caller should then handle that promise by chaining more `.then(…)` calls to it. – Bergi Apr 10 '20 at 19:58
  • @Bergi thanks. Is it accepted to actually access/use the promise outside the function passed to `then()` (EX: in the function calling `canActivate()` which receives an unfulfilled promise), and if so, how do we usually check that the promise has been resolved since the `.then(expr)` `expr` function runs asynchronously and the promise may not have been fulfilled yet? – TheThing Apr 10 '20 at 20:00
  • @Bergi, oh right, you would just chain another `.then()` call in a different scope. Makes a lot of sense. Thanks for the explanation :) – TheThing Apr 10 '20 at 20:01
  • @Bergi final question, if the `.then()` callback is fired asynchronously, would the surrounding scope not get destroyed when returning the unresolved promise? Does the unexecuted callback within `.then()` prevent that from happening to prevent errors? Does it run with no issue despite the scope being destroyed since the only member variable we reference is a reference to a global injection (`this.router`). This is in angular by the way, let me know if there's angular stuff going on you aren't familiar with here. – TheThing Apr 10 '20 at 20:08
  • @TheThing That's what [closures](https://stackoverflow.com/q/111102/1048572) are for – Bergi Apr 10 '20 at 21:28
0

First: please, don't post code as embedded images, it makes answering so much harder.

Second: you can just as well introduce an intermediate variable, and write your function this way:

canActivate() {
    const returnedPromise = this.authService.isAuthenticated()
        .then(this.processAuthenticationValue);

    return returnedPromise;
}


private processAuthenticationValue = (authenticated: boolean) => {
    if (authenticated) {
        return true;
    } else {
        this.router.navigate(['/']);
    }
}

So, here's what happens: isAuthenticated() is called and returns some promise. A then is attached at the end of its promise chain (that then is defined in the processAuthenticationValue method). What is returned from canActivate is the entire chain.

mbojko
  • 13,503
  • 1
  • 16
  • 26
  • I haven't tried this, but I don't think this will work. What if the `.then` fires after `return`? – Siddharth Shyniben May 28 '21 at 15:53
  • @Siddharth that's not a problem. First, that's not the case of "if", the execution _will_ reach the `return` statement before what's under `then` is executed. Second, promises exist solely for the purpose of handling this. – mbojko May 29 '21 at 09:47