对于具有多个异步调用的循环 - 在第二个异步函数中重复打印最后一个项目

问题描述 投票:0回答:1

我正在遍历一堆帖子并在循环中进行多个异步调用。我相信我理解这个问题,但我希望找到一个替代解决方案而不是我想到的解决方案。当第一个异步调用完成并触发第二个异步调用时,所有的postID都已循环通过,postID现在设置为最后一个postID。

var postIDs = {
    "abcdef": true
    "bbb456": true
    "ccc123": true
}

for(var postID in postIDs) {
  console.log("postID = " + postID);
  // check that the postID is within the postIDs to skip inherited properties
  if (postIDs.hasOwnProperty(postID)) {
    // make one async call
    admin.database().ref().child('posts').child(postID).limitToLast(1).once('value').then(snapshotForMostRecentPost => {    
      // make a second async call
      admin.database().ref().child('anotherBranch').child('someChild').once('value').then(snapshotForSomeOtherStuff => {
        console.log("postID = " + postID) // **ISSUE**: the postID is always `ccc123`
        // do some more stuff with the postID
      })
    })
  }
}

我的目标是:

abcdef
bbb456
ccc123 

相反,我得到这个结果:

ccc123
ccc123
ccc123 

可能解决方案

我可以想到解决这个问题的一种方法是将异步调用放入它们自己的函数并调用该函数,如下所示:

var postIDs = {
    "abcdef": true
    "bbb456": true
    "ccc123": true
}

for(var postID in postIDs) {
  console.log("postID = " + postID);
  // check that the postID is within the postIDs to skip inherited properties
  if (postIDs.hasOwnProperty(postID)) {
    triggerThoseAsyncCalls(postID)
  }
}

function triggerThoseAsyncCalls(postID) {
  // make one async call
  admin.database().ref().child('posts').child(postID).limitToLast(1).once('value').then(snapshotForMostRecentPost => {    
    // make a second async call      
    admin.database().ref().child('anotherBranch').child('someChild').once('value').then(snapshotForSomeOtherStuff => {
      console.log("postID = " + postID)
    })
  })
}

但是,我宁愿将此作为一个功能。有没有人知道解决这个问题的方法,而不将异步调用分离成一个单独的函数?

javascript firebase asynchronous firebase-realtime-database
1个回答
1
投票

请改用:

for(let postID in postIDs) { ... }

let具有在每次迭代时重新绑定循环变量的功能。

除了let,你可以使用postIDs.foreach()

© www.soinside.com 2019 - 2024. All rights reserved.