访问'这'promise回调中的对象(然后)

Accessing 'this' of an object inside promise callback (then)

本文关键字:对象 然后 回调 promise 访问      更新时间:2023-09-26

我想用Javascript创建一个对象。

其中一个方法应该执行承诺链。链中的每个方法都必须访问作为对象成员的配置变量。问题是,this运算符在PromiseMethod2中发生了更改,我无法访问配置变量(它在PromiseMethod1中正常工作)。

这是我的代码:

var SomeObject(config) {
    var that = this;
    that.config = config;
}
SomeObject.prototype.SomeMethod = function() {
    var that = this;
    that.PromiseMethod1()
      .then(that.PromiseMethod2)
      .catch(console.error);
    }
SomeObject.prototype.PromiseMethod1 = function() {
    var that = this;
    config = that.config;
    return SomePromise();
}
SomeObject.prototype.PromiseMethod2 = function(someParams) {
    var that = this;
    config = that.config;
    params = someParams;
    return SomePromise();
}

var someObject = new SomeObject(someConfig);
someObject.SomeMethod().then(function () {
    console.log('Done!');
}

我想在链中使用方法delegate,而不仅仅是执行:

 that.PromiseMethod1().then(function(response) { return that.PromiseMethod2(that, response); };

我不能使用bind方法,因为它看起来像是在执行回调时被重新绑定的。

有解决办法吗?为什么PromiseMethod1PromiseMethod2之间有区别?

我的real建议是根本不要使用thisnew(如果您仍然想要继承,则可以使用Object.create):

var SomeObject = function(config) {
    return {
        PromiseMethod1: function(){
            return somePromise(config.foo);
        },
        PromiseMethod2: function(x){
            return someOtherPromise(config.bar, x);
        }
    }
}
var instance = SomeObject({config: true});
instance.PromiseMethod1().then(instance.PromiseMethod2);

在这里,我使用闭包,以及它们封装父词法范围的变量的能力,这对我来说是有利的。与其依赖JavaScript在运行时根据调用函数的对象将this神奇地注入函数,因为正如您的问题所证明的那样,这并不总是有效的。

然而,我知道这是一种非传统的工作方式,所以如果你想坚持使用this,你需要使用bind来告诉JavaScript该函数属于哪个神奇的this-值:

var SomeObject function(config) {
    this.config = config;
}
SomeObject.prototype.PromiseMethod1 = function(){
    return somePromise(this.config.foo);
}
SomeObject.prototype.PromiseMethod1 = function(x){
    return someOtherPromise(this.config.bar, x);
}
var instance = new SomeObject({config: true});
instance.PromiseMethod1().then(instance.PromiseMethod2.bind(instance)); //<- :(

在您的示例SomeMethod中,您实际上并没有使用bind。您仍然需要绑定,因为您正在将函数传递到.then(f)中,而接收该函数的代码不再知道它应该为this使用哪个对象。现在再次查看我以前推荐的代码。其中没有this se,因此这些函数根本不依赖于调用它们的对象,您可以随心所欲地将它们作为高阶函数传递,而无需bindthat = this。:)

我认为这是不可能的。您尝试混合使用两种不同的方法:方法链接和承诺链接。我建议你复习一下你的体系结构。

如果您对想要使用的所有promise都有完全的控制权,那么唯一可见的事情(但我个人不喜欢)就是通过整个promise链传递配置值。

SomeObject.prototype.init = function() {
    var that = this;
    return new Promise(function(resolve, reject) {
        resolve(that.config)
    });
}
SomeObject.prototype.PromiseMethod1 = function(config, params) {
    return SomePromise(config, params);
}
SomeObject.prototype.PromiseMethod2 = function(config, someParams) {  
    return SomePromise(config, someParams);
}
SomePromise = function(config, params) {
    return new Promise(function(resolve, reject) {
        //some code here
        resolve(config, newParamsFromSomeCode)
    });
}

然后您可以拨打:

that.init().then(that.PromiseMethod1).then(that.PromiseMethod2);

但是,它看起来并不是一个好的代码。。。