javascript中两个函数之间的范围问题 [英] scope issue in javascript between two Functions

查看:98
本文介绍了javascript中两个函数之间的范围问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我尝试使用xlsx-populate获取excel工作表,因此我尝试从mailEvents集合获取值,以便可以在init Collection函数中添加或传递值.如果我解决了此问题,则我的问题excel也解决了.在此问题中,我想访问init集合中的topHeader var.在arr2中,存在以下形式的值: ['open','processed']

i have try to get the excel sheet using xlsx-populate so i am trying to get the values from mailEvents collections so i can add or pass the value in the init Collection function.if i have solved this issue then my problem regarding excel is also solved. in this problem i want to access the topHeader var in init collection. here in arr2 there is the values in this form ['open','processed']

const completeReport = (startTime,endTime) => {
    serverRef = db.collection("MailEvents");
    let getDocs = serverRef
      .where("timestamp", ">=", startTime)
      .where("timestamp", "<=", endTime)
      .get()
      .then(querySnapshot => {
        if (querySnapshot) {
          let docs = querySnapshot.docs.map(doc => doc.data());
          let arr1 = ["email", "reportName", "office"];
          let arr2 = docs.map(a => a.event);

          let topHeader = [...new Set(arr1.concat(arr2))];
        }
      });
      let query = db.collection("inits");
      let queryData = query
        .where("report", "in", ["payroll", "footprints"])

        .get()
        .then(querySnapshot => {
          if (querySnapshot) {
            let docs = querySnapshot.docs.map(doc => doc.data());
            console.log(topHeader)
          }
        });
}

所以我想要这种形式的输出

so i want the output in this form

["email", "reportName", "office",'open','processed']

推荐答案

从Firebase异步加载数据,因为返回数据可能需要一些时间.您的主代码无需等待数据返回,而是继续直接执行.然后,当数据可用时,将使用该数据调用您的 then()回调.

Data is loaded from Firebase asynchronously, since it may take some time to return. Instead of waiting for the data to return, your main code continues to execute straight away. Then when the data is available, your then() callback is called with that data.

这意味着需要访问Firestore中的数据的任何代码都必须在 then()回调内部,或从那里进行调用.

This means that any code that needs access to the data from Firestore must be inside the then() callback, or be called from there.

例如:

const completeReport = (startTime,endTime) => {
    serverRef = db.collection("MailEvents");
    let getDocs = serverRef
      .where("timestamp", ">=", startTime)
      .where("timestamp", "<=", endTime)
      .get()
      .then(querySnapshot => {
        if (querySnapshot) {
          let docs = querySnapshot.docs.map(doc => doc.data());
          let arr1 = ["email", "reportName", "office"];
          let arr2 = docs.map(a => a.event);

          let topHeader = [...new Set(arr1.concat(arr2))];

          let query = db.collection("inits");
          let queryData = serverRef
            .where("report", "in", ["payroll", "footprints"])
            .get()
            .then(querySnapshot => {
              if (querySnapshot) {
                let docs = querySnapshot.docs.map(doc => doc.data());
                console.log(topHeader)
              }
            });
        }
      });
}


有一些替代方法,尤其是当您愿意使用更现代的JavaScript构造时.最简单的方法是使用 async / await 关键字,这些关键字将以上内容包装在一些不错的语法糖中,对于大多数开发人员来说,这更常见.


There are some alternatives, especially when you're willing to use more modern JavaScript constructs. The simplest approach is to use the async / await keywords, which wrap the above in some nice syntactic sugar that reads more normal for most developers.

当您应用 async / await 时,以上代码将变为:

The above code would become this when you apply async / await:

const completeReport = async (startTime,endTime) => {
    serverRef = db.collection("MailEvents");
    let querySnapshot = await serverRef
      .where("timestamp", ">=", startTime)
      .where("timestamp", "<=", endTime)
      .get();
    if (querySnapshot) {
      let docs = querySnapshot.docs.map(doc => doc.data());
      let arr1 = ["email", "reportName", "office"];
      let arr2 = docs.map(a => a.event);

      let topHeader = [...new Set(arr1.concat(arr2))];

      let query = db.collection("inits");
      querySnapshot = await serverRef
        .where("report", "in", ["payroll", "footprints"])
        .get();
      if (querySnapshot) {
        let docs = querySnapshot.docs.map(doc => doc.data());
        console.log(topHeader)
      }
    }
}

最大的变化是:

  • completeReport 函数上的 async 标记,因为调用者需要意识到此函数现在可能会返回承诺/展示异步行为.
  • 两个 get()调用上的 await 关键字,这意味着您不再需要 then 块.
  • 减少缩进,尤其是与我的答案中的第一个片段相比.
  • The async marker on the completeReport function, since the caller needs to be aware that this function may now return a promise/exhibit async behavior.
  • The await keywords on the two get() calls, which mean you don't need a then block anymore.
  • The reduced indentation, especially when compared to the first snippet in my answer.

使用这种方法时,要始终意识到的一件事是调用仍然是异步的.虽然使用 async / await 可使代码更易于阅读,但它不会改变API的实际行为.

One of the things to always realize when using this approach is that the calls are still asynchronous. While the use of async / await makes the code easier to read, it doesn't change the actual behavior of the APIs.

这篇关于javascript中两个函数之间的范围问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆