Bluebird Promise链中类方法this指向丢失问题求助
解决Promise链式调用中类方法
this指向丢失的问题 这个问题我太熟悉了!核心原因是:当你把tc.Test1、tc.Test2这类方法直接作为回调传给.then()时,这些方法和类实例tc的绑定关系被切断了。当Promise执行回调时,this会默认指向Node.js的全局对象(严格模式下可能是undefined,但你的环境里表现为全局对象),而不是你的testClass实例。
下面给你几种靠谱的解决方案,都能让每个方法里的this始终指向类实例:
方法1:用箭头函数包裹调用(最直观的临时方案)
在.then()里用箭头函数包裹类方法的调用,箭头函数会自动继承外部作用域的this(也就是你的tc实例):
tc.printTestMessage() .then(() => tc.Test1()) .then(() => tc.Test2()) .then(() => tc.Test3());
这样每次调用Test1()、Test2()时,this都会指向tc,完美保留上下文。
方法2:用bind()提前绑定this
bind()方法会返回一个新函数,强制把函数的this绑定到指定对象上。你可以在传回调的时候直接绑定:
tc.printTestMessage() .then(tc.Test1.bind(tc)) .then(tc.Test2.bind(tc)) .then(tc.Test3.bind(tc));
这种方式也能固定this指向,适合不想写箭头函数的场景。
方法3:在构造函数里提前绑定所有方法(一劳永逸)
如果这个类的方法经常要作为回调使用,推荐在构造函数里一次性把所有需要的方法绑定到实例上,之后不管怎么传方法引用,this都不会丢:
修改testClass.js的构造函数:
let testClass = function(dbg) { let self = this; self._dbg = dbg; // 提前绑定所有需要的方法 self.Test1 = self.Test1.bind(self); self.Test2 = self.Test2.bind(self); self.Test3 = self.Test3.bind(self); };
之后你的原调用代码不需要任何修改,直接传tc.Test1就可以了:
tc.printTestMessage() .then(tc.Test1) .then(tc.Test2) .then(tc.Test3);
方法4:改用ES6类语法+箭头函数方法(现代写法)
如果你的项目支持ES6,更推荐用class语法,并且把类方法写成箭头函数,这样箭头函数会自动绑定实例的this:
重构后的testClass.js:
"use strict"; const Promise = require("bluebird"); class testClass { constructor(dbg) { this._dbg = dbg; } printTestMessage() { return new Promise((resolve) => { this._dbg.printDebug(3, "testClass - printTestMessage", "start printing..."); setTimeout(() => { this._dbg.printDebug(3, "testClass - printTestMessage", "finished printing..."); resolve(); }, 2000); }); } // 用箭头函数作为类方法,自动绑定this Test1 = () => { return new Promise((resolve) => { this._dbg.printDebug(3, "testClass - Test1", "start printing..."); setTimeout(() => { this._dbg.printDebug(3, "testClass - Test1", "finished printing..."); resolve(); }, 2000); }); }; Test2 = () => { return new Promise((resolve) => { this._dbg.printDebug(3, "testClass - Test2", "start printing..."); setTimeout(() => { this._dbg.printDebug(3, "testClass - Test2", "finished printing..."); resolve(); }, 2000); }); }; Test3 = () => { return new Promise((resolve) => { this._dbg.printDebug(3, "testClass - Test3", "start printing..."); setTimeout(() => { this._dbg.printDebug(3, "testClass - Test3", "finished printing..."); resolve(); }, 2000); }); }; } module.exports = testClass;
这种写法最简洁,也不用再操心this的问题,是现在前端/Node项目的主流写法。
以上几种方法任选一种都能解决你的问题,根据你的项目环境和习惯选就行~
内容的提问来源于stack exchange,提问作者solick
相关产品推荐
相关产品推荐

