繁体   English   中英

关于JavaScript promise和“ then”语句的新手问题

[英]Newbie question about JavaScript promises and “then” statements

我对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;
  }
}

首先,您必须了解Promise主要用于异步操作,并且它们不存储值UNTIL来解析异步操作。 承诺不公开任何“ get”方法以直接检索其值,而是仅使用一个then方法来解决承诺后执行回调。 因此,使用Promise,您始终需要“等待”它解决读取值的问题。

现在,您有两种选择:

第一种是使用then()catch()的旧方法。

您使函数返回Promise(就像您所做的一样),并在调用函数的位置使用, 然后使用结果执行回调。

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的asyncawait关键字来处理您的Promises。

基本上,声明为异步的函数将始终返回Promise,并将定义允许使用await关键字的上下文。 等待将使您可以像同步代码一样编写Promise处理。

async function(){
const userData = await getUserData("anId");
console.log('the async result is' + userData);

最后,如果您需要错误处理,则需要使用try-catch包装await指令。

希望这可以帮助。

使用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);
  }
}

为了从promise获得价值,您需要使用.then ,因此在您的情况下,要在调用getUserData的行中获取数据,您需要使用相同的构造( getUserData.then((data) => {})

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM