I want to create an object in Javascript.
One of the methods should execute a promise chain. Each of the methods in the chain have to access a config variable that is a member of the object.
The problem is, the this
operator is changed in PromiseMethod2
and I can't access the config variable (It works correctly in PromiseMethod1
).
Here's my code:
var SomeObject(config) {
var that = this;
that.config = config;
}
SomeObject.prototype.SomeMethod = function() {
var that = this;
that.PromiseMethod1()
.then(that.PromiseMethod2)
.catch(console.error);
}
SomeObject.prototype.PromiseMethod1 = function() {
var that = this;
config = that.config;
return SomePromise();
}
SomeObject.prototype.PromiseMethod2 = function(someParams) {
var that = this;
config = that.config;
params = someParams;
return SomePromise();
}
var someObject = new SomeObject(someConfig);
someObject.SomeMethod().then(function () {
console.log('Done!');
}
I want to use the method delegate in the chain instead of just executing:
that.PromiseMethod1().then(function(response) { return that.PromiseMethod2(that, response); };
I can't use the bind
method because it looks like it gets rebinded when the callback is executed.
Is there a solution to this?
Why's there a difference between PromiseMethod1
and PromiseMethod2
?
Return valuereturns 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. throws an error, the promise returned by then gets rejected with the thrown error as its value.
A callback function is passed as an argument to another function whereas Promise is something that is achieved or completed in the future. In JavaScript, a promise is an object and we use the promise constructor to initialize a promise.
My real recommendation is not to use this
or new
at all (and you can use Object.create
if you still want inheritance):
var SomeObject = function(config) {
return {
PromiseMethod1: function(){
return somePromise(config.foo);
},
PromiseMethod2: function(x){
return someOtherPromise(config.bar, x);
}
}
}
var instance = SomeObject({config: true});
instance.PromiseMethod1().then(instance.PromiseMethod2);
Here I'm using closures, and their ability to enclose variables of their parent lexical scope, to my advantage. Rather than relying on JavaScript to magically inject a this
into my function at run-time based on which object the function is called on, because as demonstrated by your problem, that doesn't always work.
However, I know that its an unconventional way to work, so if you'd rather stick with this
, you'll need to use bind
in order to tell JavaScript which magical this
-value the function belongs to:
var SomeObject function(config) {
this.config = config;
}
SomeObject.prototype.PromiseMethod1 = function(){
return somePromise(this.config.foo);
}
SomeObject.prototype.PromiseMethod1 = function(x){
return someOtherPromise(this.config.bar, x);
}
var instance = new SomeObject({config: true});
instance.PromiseMethod1().then(instance.PromiseMethod2.bind(instance)); //<- :(
In your example SomeMethod
you're not actually using bind
. You still need to bind because you're passing the function into .then(f)
, and the code which receives the function doesn't know anymore which object it should use for the this
. Now look at my earlier recommended code again. There are no this
ses in there, so those functions don't rely at all on which object they're being called on, you can pass them around as higher-order-functions as much as you want without ever having to bind
or that = this
. :)
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