异步代码 运行 - 在 react-native 中使用 Javascript OOP

Async code running - using Javascript OOP in react-native

我正在做一个 react-native 项目,为了让用户操作更容易,我创建了一个 class 用户,它连接到 firebase 数据库以获取有关用户的所有信息(例如:姓名)。

但是我有一个问题,代码 运行 是异步的。如果我想做:

User.getCurrentUser().alertName(); // Display "undefined"

Userclass构造函数之前的alertName()函数运行s,其中初始化了name,所以这一行只记录"undefined".

这是用户 class:

class User {

    uid;
    object;
    name;

    constructor(id){

        firebase.database().ref('/user/'+id).once('value').then( function (snapshot) {

            this.object = snapshot.val();

            this.uid = id;
            this.name = this.object.name;

            console.log("In constructor : " + this.name);
        });
    }

    alertName(){
        console.log("From function : " + this.name);
    }

    static getCurrentUser(){
        let id = firebase.auth().currentUser.uid;
        return new User(id);
    }
}

尝试做时:

User.getCurrentUser().alertName();

控制台日志:

From function : undefined
From constructor : John

函数运行在构造函数之前,所以名字当然是undefined...

我该如何解决?

class User {

    uid;
    object;
    name;

    constructor(id){

        return firebase.database().ref('/user/'+id).once('value').then( function (snapshot) {

            this.object = snapshot.val();

            this.uid = id;
            this.name = this.object.name;
            console.log("In constructor : " + this.name);
            return this;
        });
    }

    alertName(){
        console.log("From function : " + this.name);
    }

    static getCurrentUser(){
        let id = firebase.auth().currentUser.uid;
        return new User(id);
    }

现在在调用它时做类似

的事情

User.getCurrentUser().then(user => user.alertName());


所以,这里发生的是我们从构造函数返回一个承诺,该承诺在调用数据库后用 uid, name and object 解决,然后我们返回这个,即从这个承诺返回 User。因此,当我们执行 User.getCurrentUser() 时,我们将得到一个由实际当前用户解析的承诺,并且在解析时我们将调用 currentUser 的 alertName 方法。

构造函数中的副作用可以被认为是一种反模式,异步代码就是这种情况,正是因为 class 实例化后结果将不可用。

应该公开一个承诺:

constructor(id){
    const initPromise = Promise.resolve(firebase.database().ref('/user/'+id).once('value').then( function (snapshot) {...});
}

alertName(){...}

或者手动链接:

const user = User.getCurrentUser();
await user.initPromise;
user.alertName();

或内部链接:

async alertName(){
  await this.initPromise();
  ...
}

const user = User.getCurrentUser();
await user.alertName();

在这种情况下,OOP 设计并没有太多好处。由于 React 已经鼓励函数式编程,因此没有 class.

可能会更直接