javascript 两个函数之间的范围问题
scope issue in javascript between two Functions
我尝试使用 xlsx-populate 获取 excel sheet 所以我试图从 mailEvents 集合中获取值,这样我就可以在初始集合中添加或传递值 function.if 我已经解决了这个问题然后我关于 excel 的问题也解决了。
在这个问题中,我想访问 init 集合中的 topHeader var。
在 arr2 中有这种形式的值 ['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)
}
});
}
所以我想要这种形式的输出
["email", "reportName", "office",'open','processed']
由于 let 具有块作用域,因此外部无法访问它。
建议您使用 var
声明一个变量,稍后再赋值。
希望对您有所帮助!
const completeReport = () => {
let serverRef = db.collection("MailEvents");
var topHeader;
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);
topHeader = [...new Set(arr1.concat(arr2))]; //assign value
}
});
serverRef = 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)
}
});
}
数据是从 Firebase 异步加载的,因为 return 可能需要一些时间。您的主代码不会等待数据达到 return,而是会立即继续执行。然后,当数据可用时,您的 then()
回调将使用该数据调用。
这意味着任何需要从 Firestore 访问数据的代码都必须在 then()
回调中,或者从那里调用。
例如:
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
关键字,将上面的内容包装在一些对大多数开发人员来说更正常的语法糖中。
当你应用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
标记,因为调用者需要知道此函数现在可能 return 一个 promise/exhibit 异步行为。
- 两个
get()
调用中的 await
关键字,这意味着您不再需要 then
块。
- 减少缩进,尤其是与我回答中的第一个片段相比时。
使用这种方法时要始终意识到的一件事是调用仍然是异步的。虽然使用 async
/ await
使代码更易于阅读,但它不会改变 API 的实际行为。
我尝试使用 xlsx-populate 获取 excel sheet 所以我试图从 mailEvents 集合中获取值,这样我就可以在初始集合中添加或传递值 function.if 我已经解决了这个问题然后我关于 excel 的问题也解决了。
在这个问题中,我想访问 init 集合中的 topHeader var。
在 arr2 中有这种形式的值 ['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)
}
});
}
所以我想要这种形式的输出
["email", "reportName", "office",'open','processed']
由于 let 具有块作用域,因此外部无法访问它。
建议您使用 var
声明一个变量,稍后再赋值。
希望对您有所帮助!
const completeReport = () => {
let serverRef = db.collection("MailEvents");
var topHeader;
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);
topHeader = [...new Set(arr1.concat(arr2))]; //assign value
}
});
serverRef = 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)
}
});
}
数据是从 Firebase 异步加载的,因为 return 可能需要一些时间。您的主代码不会等待数据达到 return,而是会立即继续执行。然后,当数据可用时,您的 then()
回调将使用该数据调用。
这意味着任何需要从 Firestore 访问数据的代码都必须在 then()
回调中,或者从那里调用。
例如:
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
关键字,将上面的内容包装在一些对大多数开发人员来说更正常的语法糖中。
当你应用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
标记,因为调用者需要知道此函数现在可能 return 一个 promise/exhibit 异步行为。- 两个
get()
调用中的await
关键字,这意味着您不再需要then
块。 - 减少缩进,尤其是与我回答中的第一个片段相比时。
使用这种方法时要始终意识到的一件事是调用仍然是异步的。虽然使用 async
/ await
使代码更易于阅读,但它不会改变 API 的实际行为。