带有 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);
serviceMethod
的 Service
对象返回一个承诺。
当我使用User
对象时,如下所示:
let user = new User(args);
user.method1();
method2
对象 User
中的this
在被 then
调用时,一旦实现承诺,就会结束 undefined
。
我尝试同时使用 ES6 和 Bluebird 承诺实现。
在这种情况下,为什么 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