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

异步代码运行-在react native中使用Javascript OOP,javascript,reactjs,react-native,javascript-objects,es6-class,Javascript,Reactjs,React Native,Javascript Objects,Es6 Class,我正在做一个react原生项目,为了让用户操作更容易,我创建了一个类User,它连接到firebase数据库以获取有关用户的所有信息(例如:名称) 但是我有一个问题,代码是异步运行的。如果我想做: User.getCurrentUser().alertName(); // Display "undefined" alertName()函数在初始化名称的用户类构造函数之前运行,因此此行只记录“undefined” 以下是用户类: class User { uid; object

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

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

User.getCurrentUser().alertName(); // Display "undefined"
alertName()
函数在初始化名称的用户类构造函数之前运行,因此此行只记录“undefined”

以下是用户类:

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();
控制台日志:

来自函数:未定义
作者:约翰

函数在构造函数之前运行,因此名称当然是未定义的

我怎样才能修好它

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()。然后(User=>User.alertName())


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

现在,在调用它时,请执行以下操作


User.getCurrentUser()。然后(User=>User.alertName())



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

构造函数中的副作用可以被视为反模式,异步代码就是这样,正是因为在类实例化之后,结果将不可用

承诺应当公开:

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


在这种情况下,OOP设计没有多少好处。由于React已经鼓励函数式编程,因此在没有类的情况下,它可能更简单。

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

承诺应当公开:

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


在这种情况下,OOP设计没有多少好处。因为React已经鼓励函数式编程,所以不需要类就可以更简单。

这个想法是可行的,因为控制台首先记录“In constructor”。但是我有一个关于承诺的错误:“[Unhandled promise rejection:TypeError:undefined不是一个对象(评估'user.alertName')]”这个想法有效,因为控制台首先记录“In constructor”。但是我对承诺有一个错误:“[未处理的承诺拒绝:TypeError:undefined不是对象(评估'user.alertName')”