ES6级承诺链 - 访问'this'

1do*_*ski 3 javascript class promise ecmascript-6

我想在我的第二个承诺中引用一个类属性.但是,在类函数pTwo中,'this'是未定义的.我知道我处于承诺范围内,我如何访问PromiseChain实例范围?

使用ES6和本机承诺.

class PromiseChain {
    constructor(){
        this.food = 'Pasta';
        this.type = 'Italian';
    }

    pOne() {
        console.log('pOne');
        return Promise.resolve();
    }

    pTwo() {
        console.log('pTwo');
        try {
            console.log(this.food);
        } catch (e) {
            // can't read 'food' of undefined! 
            console.log(e);
        }
        return Promise.reject()
    }

    work() {
        console.log('Get to work!');
        this.pOne().then(this.pTwo).catch((error) => {
            console.log(error);
        })
    }
}

new PromiseChain().work();
Run Code Online (Sandbox Code Playgroud)

Ale*_*lex 6

这很简单,你需要将你的调用绑定pTwo到正确的范围,在Javascript中我们可以用这个bind()方法做到这一点.

因此:

this.pOne().then(this.pTwo.bind(this)).catch((error) => {
Run Code Online (Sandbox Code Playgroud)

将您对pTwo的调用绑定到正确的范围,从而导致:

Get to work!
pOne
pTwo
Pasta
undefined
Run Code Online (Sandbox Code Playgroud)

要印刷; 如果您希望最后一个undefined返回一些内容,请在reject参数中传递一条消息.

如果您不想使用大量的代码库混乱,.bind(this)您可以this在当前范围中显式设置引用,并将其作为参数传递给您的每个承诺; 在你的情况下,work方法声明:

work() {
    var that = this;
    console.log('Get to work!');
    this.pOne().then(this.pTwo(that).catch((error) => {
        console.log(error);
    }));
}
Run Code Online (Sandbox Code Playgroud)

请注意,现在pTwo接受一个参数that,现在pTwo我们可以执行以下操作:

pTwo(parentScope) {
    console.log('pTwo');
    try {
        console.log(parentScope.food);
    } catch (e) {
        // can't read 'food' of undefined! 
        console.log(e);
    }
    return Promise.reject()
}
Run Code Online (Sandbox Code Playgroud)

请注意,我们传递的参数parentScope允许我们引用正确的范围.