In the bellow example, when I am running this code, calling the start function, only inside _one function this is defined. When continuing to the next function _two, this is undefined. Any explanation? And how to solve this?
Thanks in advance.
'use strict';
class MyClass {
constructor(num) {
this.num = num;
}
start() {
this._one()
.then(this._two)
.then(this._three)
.then(this._four)
.catch((err) => {
console.log(err.message);
});
}
_one() {
console.log('num: ' + this.num);
return new Promise((resolve, reject) => {
resolve();
});
}
_two() {
console.log('num: ' + this.num);
return new Promise((resolve, reject) => {
resolve();
});
}
_three() {
console.log('num: ' + this.num);
return new Promise((resolve, reject) => {
resolve();
});
}
_four() {
console.log('num: ' + this.num);
return new Promise((resolve, reject) => {
resolve();
});
}
}
let myClass = new MyClass(4);
myClass.start();
Modify the promises chain to this:
start() {
this._one()
.then(this._two.bind(this))
.then(this._three.bind(this))
.then(this._four.bind(this))
.catch((err) => {
console.log(err.message);
});
}
The bind() will modify handlers to bind with the correct this object (the instance of MyClass). You will achieve the method invocation on MyClass instance.
Following your initial scenario, the Promise will invoke the handlers (_two, _three) as regular functions, which in Strict mode will have this as undefined.
See here more details about bind().
I am personnaly using bluebird promises rather then native ES6.
This promises perform faster (https://github.com/petkaantonov/bluebird/tree/master/benchmark), have more convinient API and available in both browsers and node.js (http://bluebirdjs.com/docs/getting-started.html)
I am bind this value to the first promise in chain - after that your example works well
'use strict';
var Promise = require('bluebird');
class MyClass {
constructor(num) {
this.num = num;
}
start() {
Promise.bind(this)
.then(this._one)
.then(this._two)
.then(this._three)
.then(this._four)
.catch((err) => {
console.log(err.message);
});
}
_one() {
console.log('num: ' + (this.num += 1));
return new Promise((resolve, reject) => {
resolve();
});
}
_two() {
console.log('num: ' + (this.num += 2));
return new Promise((resolve, reject) => {
resolve();
});
}
_three() {
console.log('num: ' + (this.num += 3));
return new Promise((resolve, reject) => {
resolve();
});
}
_four() {
console.log('num: ' + (this.num += 4));
return new Promise((resolve, reject) => {
resolve();
});
}
}
let myClass = new MyClass(4);
myClass.start();
I've also changed methods slightly so that you can see progress in this.num
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