我正在开发一个小型纸牌游戏网络应用程序。我正在使用“房间”系统来容纳每个游戏及其玩家。每个房间都有一个玩家列表,我需要过滤此列表以仅获取在Firebase Realtime DB中具有值的玩家列表。在这种情况下,我正在检查他们在/status/{userId}
中的用户状态。
我认为我可以很简单地将其组合在一起,但是在过滤器完成之前,已读取了过滤后的players
数组或activePlayers
。
与forEach一起演示:
function debugActivePlayers (players) {
activePlayers = []
players.forEach(player => {
firebase.ref('/status/' + player)
.once('value')
.then(snapshot => {
console.log(snapshot.val()) // 'offline' or 'online' accordingly
if (snapshot.val() === 'online') activePlayers.push(player)
return null // <-- IDE throws a fit otherwise lol
})
})
console.log(activePlayers)
}
我希望发生的是:
offline
online
online
[userId1, userId2, userId3]
但是真正发生的是:
[]
offline
online
online
即使内部有异步/承诺逻辑(firebase查询),我如何确保players.forEach
(或players.filter
)也能同步运行?
答案 0 :(得分:1)
尝试使用“异步/等待”,如下所示。这将等待所有异步调用完成,然后前进到最后一个console.log
async function debugActivePlayers (players) {
let activePlayers = []
for (let player of players) {
let snapshot = await firebase.ref('/status/' + player).once('value')
console.log(snapshot.val()) // 'offline' or 'online' accordingly
if (snapshot.val() === 'online') activePlayers.push(player)
return null // <-- IDE throws a fit otherwise lol
}
console.log(activePlayers)
}
说明-“ for..of”与“ await”使其余语句保持执行状态,直到所有promise都被解决为止。以证明下面的pls测试
function getValue(p) { return Promise.resolve(p) }
async function test (players = [1,2,3]) {
for (let player of players) {
console.log(await getValue(player))
}
console.log('done')
}
test()