1

此示例中的函数doSomethingElse无法执行,因为它this已被重新绑定到windowor global(如果在 Node 中)由于内部的无上下文调用app.populateDatabase

有没有办法在不引用app每个函数的情况下避免这种情况?

loadDatabase函数根据逻辑语句执行回调,如果虚构的数据库不存在,则在加载后填充它,然后populateDatabase执行已提供的回调。

我无法重新绑定onLoaded参数,app因为我不知道它来自哪里,并且绑定/应用/调用抽象过度使用造成了相当混乱。

var app = {};
app.loadDatabase = function(onLoaded) {

    // If database already exists, only run a callback
    var callback = onLoaded;

    // If database doesn't exists, populate it, then run a callback.
    if (!databaseExists) {
        callback = this.populateDatabase.bind(this, onLoaded);
    }

    this.database = new sqlite.Database("file.db", function(error) {
        if (error) { ... }

        callback();
    })

}

app.populateDatabase = function(onPopulated) {

    // Contextless call here. <--------
    onPopulated();
}

app.doSomethingElse = function() {

    // this != app due to contextless call.
    this.somethingElse();
}

app.run = function() {

    // Load the database, then do something else.
    this.loadDatabase(this.doSomethingElse);
}

app.run();
4

1 回答 1

3

只需替换this.loadDatabase(this.doSomethingElse); this.loadDatabase(() => this.doSomethingElse());. 这样你就可以创建一个新的箭头函数,然后doSomethingElse用正确的this上下文调用。

您也可以这样做.bind,但我推荐使用箭头功能。在这里bindthis.loadDatabase(this.doSomethingElse.bind(this))


一般来说,考虑转向承诺和异步功能。然后这样做:

this.loadDatabase().then(() => this.doSomethingElse());

或更好的异步功能:

await this.loadDatabase();
this.doSomethingElse();
于 2018-09-07T23:35:35.033 回答