return 语句在变量的 foreach 之外返回 null 值,我知道 foreach 循环创建了自己的作用域,我需要返回该值,我该怎么做......
this.selectedUserMessages = this.changeUserList.switchMap(Userid => {
if (Userid) {
var self = this;
this.loadingSerivice.isLoading.next(true);
var ref = db.database.ref(`wfffsdf/usesdfdsfsrs/${Userid}/ress`);
var i = 0;
ref.once("value")
.then(function(snapshot) {
snapshot.forEach(function(childSnapshot) {
var key = childSnapshot.key;
// childData will be the actual contents of the child
var invitedList = childSnapshot.val();
self.invList.push({
invitedid: invitedList
});
var invitedlistid = self.invList[i]['invitedid']['invitedBy'];
//console.log(invitedlistid);
if (invitedlistid == "asfsafafasfsafsafs") {
//console.log("thread"+threadKey);
self.ChatKey = key;
//console.log(self.ChatKey+""+ db.database.ref(`1dfgsdfgdfhfdh/tdfsdfhsfhfhfdh/${key}/messages`));
}
i++;
});
self.chatMessages = self.getMessages(self.ChatKey);
// console.log(self.chatMessages);
});
return this.chatMessages;
}
return of(null);
}
返回 this.chatMessages 给空值...
最佳答案
简单的回答是变量的范围不是问题。在 Javascript 中,var
的作用域为周围的函数。在提供的示例代码中,forEach
被传递给一个function
,因此它的所有变量的作用域都如声明的那样。外部变量在内部函数中被捕获,因此它们的行为也正常。
问题在于,在 switchmap
返回值之前,内部 promise
未得到解析。
为了充分理解发生了什么,让我们看一下代码当前正在做什么以及它应该做什么。
为了论证,我将假设以下定义(即使我知道它们不正确):
selectedUserMessages : Observable<[]>;
changeUserList : Observable<String>;
这里,changeUserList
是一个字符串事件流,表示当前选定的UserId
。 selectedUserMessages
将是与当前所选用户关联的消息数组。
上面的代码简化后的意思如下:
this.selectedUserMessages =
// when changeUserList changes, switch selectedUserMessages to this new stream
this.changeUserList.switchMap(Userid => {
if (Userid) {
// grab DB reference to user child list
var ref = db.database.ref(`wfffsdf/usesdfdsfsrs/${Userid}/ress`);
// CREATE A PROMISE TO QUERY THE DATABASE
ref.once("value") // query once
.then(function (snapshot) {
snapshot.forEach(function (childSnapshot) {
var key = childSnapshot.key;
var val = childSnapshot.val();
// process child
});
// store result
this.chatMessages = this.getMessages(this.ChatKey);
}); // END OF PROMISE
// RETURN IMMEDIATELY, BEFORE PROMISE RESOLVES
return this.chatMessages;
}
return of(null); // return null stream
}
问题是 switchmap 调用在内部 promise 解析之前返回 this.chatMessages
。
switchmap
有一个有趣的功能:您可以从 switchmap 内部返回一个 promise ,并且它将等待该 promise 。这是 mix Promises and Observables 的一种方法.
从 switchmap 内部返回一个 promise 看起来像:
this.selectedUserMessages =
// when changeUserList changes, switch selectedUserMessages to this new stream
this.changeUserList.switchMap(Userid => {
if (Userid) {
// grab DB reference to user child list
let ref = db.database.ref(`wfffsdf/usesdfdsfsrs/${Userid}/ress`);
// !!!! RETURN A PROMISE TO QUERY THE DATABASE !!!!
return ref.once("value") // query once
.then(function (snapshot) {
let results = [];
snapshot.forEach(function (childSnapshot) {
let key = childSnapshot.key;
let val = childSnapshot.val();
// process child //
results.push(/*processing results*/);
});
return results;
}); // END OF PROMISE
}
else
return of(null); // return null stream
}
<小时/>
话虽如此,对于 Firebase 来说,还有一种混合 Promise 和 Observables 的替代方案,称为 RxFire 。它是 Firebase 团队提供的一个相对较新的软件包,用于使用 RxJS Observables。由于您使用的是实时数据库,因此您需要look at these examples 。 List() 将发出子级更改流。您可以通过 map()
运算符pipe()
此流来执行其他处理(或提取 val() 并包含示例中的键)。您在 map() 中所做的操作与您在 forEach
中所做的操作类似。
AngularFirebase有一个在 FireStore 上使用 RxFire 的示例。
关于javascript - 如何在 snapshot.foreach 中访问超出其范围的变量值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52274249/