我对JavaScript还是很陌生,并且发现promise和“ then”语句的概念真的很难确定。我正在使用Firebase的网站上工作,并且试图从数据库中获取用户数据。这是我目前的情况:
// Function that fetches a user's data from the database.
getUserData = function(uid) {
var database = firebase.firestore();
var docRef = database.collection('users').doc(uid);
var userData = docRef.get().then(function(doc) {
if (doc.exists) {
return doc.data();
} else {
console.log("User does not exist.");
return null;
}
}).catch(function(error) {
console.log("Error getting document:", error);
});
return userData;
}
当前,此函数返回Promise对象。当我将对象记录到控制台时,它说承诺状态已解决,其值是doc.data()的值。我真正想要的是将doc.data()的值传递回“链”上,传递给getUserData函数,以便我可以在其他地方返回和使用它。有没有简单的方法可以做到这一点?我试图找到一种方法来从对象本身中获取Promise的“值”,但是我什么也没发现,到目前为止,我还没有找到其他方法来实现自己想要的目标。
我敢肯定,这比看起来要简单得多,我觉得自己是个白痴,想问这样的事情,但是我已经花了几个小时了,我发现的任何解释都没有帮助。我将不胜感激任何建议。谢谢!
编辑:已解决!谢谢大家的帮助!以防万一这对将来偶然发现它的人有所帮助,我在这里保留我的最终(工作)代码。不幸的是,无法从同步函数中调用它,但是对于我的目的而言,它最终已经足够好了:
// Function that fetches a user's data from the database.
async function getUserData(uid) {
var database = firebase.firestore();
var docRef = database.collection('users').doc(uid);
var doc = await docRef.get();
if (doc.exists) {
return doc.data();
} else {
console.log("User does not exist.");
return null;
}
}
答案 0 :(得分:1)
首先,您必须了解Promise主要用于异步操作,并且它们不存储值UNTIL异步操作已解决。 承诺不公开任何“ get”方法以直接检索其值,而是仅使用一个 then 方法在承诺被解决后执行回调。因此,使用Promise,您始终需要“等待”它解决读取值的问题。
现在,您有两种选择:
首先是使用then()
和catch()
的旧方法。
让您的函数返回Promise(就像您所做的一样),然后在调用函数的地方使用 then 执行结果回调。
getUserData("anId").then((userData) => console.log('the async result is' + userData))
您还可以使用catch来处理错误:
getUserData("anId")
.then((userData) => console.log('the async result is' + userData))
.catch((error) => console.error('wooopsie : ' + error))
对于“新的”工作方式,可以使用JS的 async 和 await 关键字来处理您的承诺。
基本上,声明为异步的函数将始终返回Promise,并将定义允许使用await关键字的上下文。并且等待将使您能够像同步代码一样编写Promise处理。
async function(){
const userData = await getUserData("anId");
console.log('the async result is' + userData);
最后,如果需要错误处理,则需要用try-catch包裹 await 指令。
希望这会有所帮助。
答案 1 :(得分:1)
使用promise的原因是它们使异步代码更易于使用。不幸的是,如果您不习惯该代码,它仍然会有些棘手。在大多数情况下,使用async / await可能会更好,因为它使用起来更容易,也可能更容易理解:
async function getUserData(uid) {
var database = firebase.firestore();
var docRef = database.collection('users').doc(uid);
var doc = await docRef.get();
if(doc.exists)
return doc.data();
return null;
}
这是您将如何使用它:
// code to execute before
getUserData(uid).then(userData => {
if(userData) {
// code to execute after
}
else console.log("User does not exist.");
}).catch(error => {
console.log("Error getting document:", error);
});
或者(异步/等待):
async function doSomething(uid) {
// code to execute before
const userData = await getUserData(uid);
// code to execute after
}
使用自定义错误处理进行异步/等待:
async function doSomething(uid) {
// code to execute before
try {
const userData = await getUserData(uid);
if(userData) {
// code to execute after
}
else console.log("User does not exist.");
}
catch(error) {
console.log("Error:", error);
}
}
答案 2 :(得分:0)
要从承诺中获得价值,您需要使用.then
,因此,要在调用getUserData
的行中获取数据,您需要使用相同的构造(getUserData.then((data) => {})
)< / p>