Saro Saro - 6 months ago 8
Javascript Question

The `this` object is undefined when using promise

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();

Answer

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