简体   繁体   English

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

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

I want to create an object in Javascript. 我想在Javascript中创建一个对象。

One of the methods should execute a promise chain. 其中一个方法应该执行一个promise链。 Each of the methods in the chain have to access a config variable that is a member of the object. 链中的每个方法都必须访问作为对象成员的配置变量。 The problem is, the this operator is changed in PromiseMethod2 and I can't access the config variable (It works correctly in PromiseMethod1 ). 问题是,在PromiseMethod2更改了this运算符,我无法访问配置变量(它在PromiseMethod1正常PromiseMethod1 )。

Here's my code: 这是我的代码:

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!');
}

I want to use the method delegate in the chain instead of just executing: 我想在链中使用方法委托而不是仅执行:

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

I can't use the bind method because it looks like it gets rebinded when the callback is executed. 我不能使用bind方法,因为它看起来像在执行回调时被重新bind

Is there a solution to this? 这个问题有方法解决吗? Why's there a difference between PromiseMethod1 and PromiseMethod2 ? 为什么PromiseMethod1PromiseMethod2之间存在差异?

My real recommendation is not to use this or new at all (and you can use Object.create if you still want inheritance): 真正的建议是不要使用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);

Here I'm using closures, and their ability to enclose variables of their parent lexical scope, to my advantage. 在这里,我正在使用闭包,以及它们包含其父词法范围变量的能力,这对我有利。 Rather than relying on JavaScript to magically inject a this into my function at run-time based on which object the function is called on, because as demonstrated by your problem, that doesn't always work. 而不是依赖于JavaScript奇迹般地注入this基于哪个对象被调用的函数上,因为你的问题,因为表现出对进入我在运行时功能,这并不总是工作。

However, I know that its an unconventional way to work, so if you'd rather stick with this , you'll need to use bind in order to tell JavaScript which magical this -value the function belongs to: 但是,我知道它是一种非传统的工作方式,所以如果你更愿意坚持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)); //<- :(

In your example SomeMethod you're not actually using bind . 在你的示例SomeMethod你实际上并没有使用bind You still need to bind because you're passing the function into .then(f) , and the code which receives the function doesn't know anymore which object it should use for the this . 您仍然需要绑定,因为你传递函数成.then(f)以及接收功能的代码已经不知道哪个对象应使用在this Now look at my earlier recommended code again. 现在再看看我之前推荐的代码。 There are no this ses in there, so those functions don't rely at all on which object they're being called on, you can pass them around as higher-order-functions as much as you want without ever having to bind or that = this . 那里没有this ses,所以这些函数根本不依赖于它们被调用的对象,你可以将它们作为高阶函数传递给你想要的,而不必bindthat = this :) :)

I would say that's impossible. 我会说这是不可能的。 You try to mix 2 different approaches: method chaining and promises chaining . 您尝试混合使用两种不同的方法: 方法链接承诺链接 I'd recommend to review your architecture. 我建议您检查一下您的架构。

The only visible thing (but personally I don't like it) if you have a full control over all promises that you want to use is to pass config values through the whole promises chain. 唯一可见的东西(但我个人并不喜欢),如果你完全控制你想要使用的所有承诺,就是通过整个promises链传递配置值。

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)
    });
}

Then you'll be able to call: 然后你就可以打电话:

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

But again, it doesn't look like a good code... 但同样,它看起来不是一个好的代码......

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM