如何使数组过滤器与异步函数端一起使用? [复制]

Posted

技术标签:

【中文标题】如何使数组过滤器与异步函数端一起使用? [复制]【英文标题】:How to make an array filter work with an async function side? [duplicate] 【发布时间】:2019-04-16 15:56:24 【问题描述】:

我正在开发一个小型纸牌游戏网络应用程序。我正在使用“房间”系统来保存每场比赛及其球员。每个房间都有一个玩家列表,我需要过滤此列表以仅获取在 Firebase 实时数据库中具有值的玩家列表。在这种情况下,我在/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

我如何确保players.forEach(或players.filter)同步运行,即使内部有异步/承诺逻辑(firebase 查询)?

【问题讨论】:

请不要为您的问题添加解决方案。 【参考方案1】:

尝试使用“async/await”,如下所示。这将等待所有异步调用完成,然后前进到最后一个 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 使剩余语句的执行暂停,直到所有承诺都得到解决。为了证明请在下面进行测试

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()

【讨论】:

不知道为什么这与他已经使用的代码有什么不同...console.log 不是异步的... 是的,console.log 看起来不是异步的,但是 "for..of" 和 "await" 使剩余的执行等待直到每个承诺都得到解决。 @PariBaker 为此添加了示例说明。请看一下。 我不敢相信我错过了这么简单的事情。有关我刚刚发布(或即将发布)的最终代码,请参阅我的原始帖子。 function debugActivePlayers(players) let activePlayers = player.map(player => return firebase .ref("/status/" + player) .once("value") .then(snapshot = > console.log(snapshot.val()); if (snapshot.val() === "online") return player; else return; ); );

以上是关于如何使数组过滤器与异步函数端一起使用? [复制]的主要内容,如果未能解决你的问题,请参考以下文章

如何使函数与Scala中的任何数字类型的集合一起使用

如何使分页与过滤 django 一起使用?

如何将 Array.prototype.filter 与异步一起使用?

如何使 UIScrollView 与自动布局和动态内容一起使用? [复制]

如何使用 JavaScript 中的索引过滤数组数组? [复制]

useState 是同步的吗? [复制]