异步代码 运行 - 在 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.
可能会更直接
我正在做一个 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.
可能会更直接