A variable that has not been assigned a value is of type undefined . A method or statement also returns undefined if the variable that is being evaluated does not have an assigned value. A function returns undefined if a value was not returned .
Problem Statement: You need to first declare a promise using its basic syntax in JavaScript and further executing the pre-declared promise you need to create another promise which is to be called inside the previous promise for its execution.
If a handler function: returns a value, the promise returned by then gets resolved with the returned value as its value. doesn't return anything, the promise returned by then gets resolved with an undefined value.
A promise is just an object with properties in Javascript. There's no magic to it. So failing to resolve or reject a promise just fails to ever change the state from "pending" to anything else. This doesn't cause any fundamental problem in Javascript because a promise is just a regular Javascript object.
this
is always the object the method is called on. However, when passing the method to then()
, you are not calling it! The method will be stored somewhere and called from there later. If you want to preserve this
, you will have to do it like this:
.then(() => this.method2())
or if you have to do it the pre-ES6 way, you need to preserve this
before:
var that = this;
// ...
.then(function() { that.method2() })
Promise handlers are called in the context of the global object (window
) by default. When in strict mode (use strict;
), the context is undefined
. This is what's happening to method2
and method3
.
;(function(){
'use strict'
Promise.resolve('foo').then(function(){console.log(this)}); // undefined
}());
;(function(){
Promise.resolve('foo').then(function(){console.log(this)}); // window
}());
For method1
, you're calling method1
as this.method1()
. This way of calling it calls it in the context of the this
object which is your instance. That's why the context inside method1
is the instance.
Basically, you're passing it a function reference with no context reference. The this
context is determined in a few ways:
myObj.f()
then myObj
is going to be the this
context.**.bind
and .apply
. These you explicitly state what the this
context is. These always take precedence over the previous two.In your example, you're passing a function reference, so at it's invocation it's implied to be a global function or one without context. Using .bind
resolves this by creating a new function where this
is explicitly set.
*This is only true in non-strict mode. In strict mode, this
is set to undefined
.
**Assuming the function you're using hasn't been manually bound.
One way functions get their context (this
) is from the object on which they are invoked (which is why method1
has the right context - it's invoked on this
). You are passing a reference to the function itself to then
. You can imagine that the implementation of then
looks something like this:
function then( callback ) {
// assume 'value' is the recently-fulfilled promise value
callback(value);
}
In that example callback
is a reference to your function. It doesn't have any context. As you've already noted you can get around that by binding the function to a context before you pass it to then.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With