带有 ES6 / Bluebird 承诺的对象方法

Posted

技术标签:

【中文标题】带有 ES6 / Bluebird 承诺的对象方法【英文标题】:Object method with ES6 / Bluebird promises 【发布时间】:2015-01-24 18:34:41 【问题描述】:

我在带有harmony 标志的 Windows 上使用 node v0.11.14-nightly-20140819-pre

我的 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);

serviceMethodService 对象返回一个承诺。

当我使用User 对象时,如下所示:

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

method2 对象 User 中的this 在被 then 调用时,一旦实现承诺,就会结束 undefined

我尝试同时使用 ES6Bluebird 承诺实现。

在这种情况下,为什么 this 最终会变成 undefined

【问题讨论】:

【参考方案1】:

在这种情况下,为什么 this 最终会变成 undefined

因为您传递的是函数,而不是方法绑定到实例。这个问题甚至不是特定于承诺的,请参阅How to access the correct `this` context inside a callback? 以获得通用解决方案:

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

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

但是,Bluebird does offer 将函数作为方法调用的另一种方式:

this.service.serviceMethod(args)
    .bind(this)
    .then(this.method2)
    .catch(onRejected);

【讨论】:

【参考方案2】:

我应该补充一点,这是一个通用的 Javascript 问题,也可以使用普通的 javascript 功能来解决。例如,您也可以这样做:

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

这使用了Function.prototype.bind(),它内置在 Javascript 中并出现在每个函数中。这将创建一个函数存根(这是传递给.then() 的内容,并且该存根将在调用method2() 之前自动重新附加所需的this 值。

【讨论】:

这就是我最终为了保持与 es6 承诺兼容而做的事情 我最终使用了这个解决方案,并且在使用单独的原型方法过于冗长的情况下使用了粗箭头语法。我相信两者都兼容 ES6+。

以上是关于带有 ES6 / Bluebird 承诺的对象方法的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 Bluebird 承诺 NodeJS Express

与 fs 和 bluebird 的承诺

使用 Bluebird 手动承诺 pg.connect

使用Bluebird承诺创建限制功能

无法得到我在 nodejs / mongoose / bluebird 中返回的承诺

非 Promise 值的“等待”无效(Bluebird 承诺)