Метод объекта с обещаниями ES6/Bluebird

Я использую node v0.11.14-nightly-20140819-pre в Windows с флагом harmony.

У меня есть объект JavaScript с двумя методами, определенными в его прототипе:

function User (args) {
    this.service= new Service(args);
}

User.prototype.method2 = function (response) {
    console.log(this); // <= UNDEFINED!!!!
};

User.prototype.method1 = function () {
    .............
    this.service.serviceMethod(args)
        .then(this.method2)
        .catch(onRejected);
};

function onRejected(val) {
    console.log(val);
}

serviceMethod из Service объекта возвращает обещание.

Когда я использую объект User, как показано ниже:

let user = new User(args);
user.method1();

this в method2 объекта User заканчивается undefined при вызове then после выполнения обещания.

Я пытался использовать реализацию промисов ES6 и Bluebird.

Почему в данном случае this оказывается undefined?


person krl    schedule 26.11.2014    source источник


Ответы (2)


Почему this в этом случае оказывается undefined?

Потому что вы передаете функцию, а не метод, привязанный к экземпляру. Эта проблема даже не связана с промисом, см. Как получить доступ к правильному контексту this внутри обратного вызова? для общего решение:

….then(this.method2.bind(this))… // ES5 .bind() Function method

….then((r) => this.method2(r))… // ES6 arrow function

Однако Bluebird предлагает другой способ вызова функции как метода:

this.service.serviceMethod(args)
    .bind(this)
    .then(this.method2)
    .catch(onRejected);
person Bergi    schedule 26.11.2014

Я должен добавить, что это общая проблема Javascript, и ее также можно решить с помощью простых функций javascript. Например, вы также можете сделать это:

User.prototype.method1 = function () {
    .............
    this.service.serviceMethod(args)
        .then(this.method2.bind(this))
        .catch(onRejected);
};

При этом используется Function.prototype.bind(), встроенный в Javascript и присутствующий в каждой функции. Это создает заглушку функции (это то, что передается в .then(), и эта заглушка автоматически повторно присоединит желаемое значение this перед вызовом method2().

person jfriend00    schedule 26.11.2014
comment
это то, что я сделал, чтобы сохранить совместимость с обещаниями es6 - person krl; 27.11.2014
comment
В итоге я использовал это решение и синтаксис толстой стрелки для случаев, когда наличие отдельного метода прототипа было слишком многословным. Я считаю, что оба совместимы с ES6+. - person Tom; 02.06.2016