【问题标题】:Chain async functions sequentially in Firebase functions在 Firebase 函数中按顺序链接异步函数
【发布时间】:2020-12-07 06:37:10
【问题描述】:

在我的功能中,我有: 2个全局变量, 1个主要入口点异步功能, 1 个异步函数调用 3 个其他异步函数

export const populateWhatsNew = functions.region('asia-east2').https.onCall((populateWhatsNewData, 
context) => {

//global variables
const interestedPeople: InterestedPerson[] = []
const whatsNewObjects: WhatsNewObject[] = []
//executing the main entry point function
return getTopInterestedPeopleAndTheirData()


//the entry point main function
async function getTopInterestedPeopleAndTheirData() {
  //this function queries multiple documents fromn firestore and adds it to interestedPeople
  //then calls an async function
  async getTheData(interestedPeople)
}


async function getTheData(theInterestedPeople: InterestedPerson[]) {
  //I want these 3 tasks in the array to be executed sequentially but
  //the order is mixed
  const tasks = [
    getCompsReceived(theInterestedPeople),
    getTheLatestInsights(theInterestedPeople),
    checkIfWhatsNewObjectsAreSufficient()
  ]

  for await (const task of tasks) {
    return task
  }

}

async function getCompsReceived(theInterestedPeople: InterestedPerson[]) {
  //queries documents from firestore and pushes it to whatsNewObjects
}

async function getTheLatestInsights(theInterestedPeople: InterestedPerson[]) {
  //queries documents from firestore and pushes it to whatsNewObjects
  theInterestedPeople.forEach(async (person) => { 
  //loop through each array to get some data
  }
}

async function checkIfWhatsNewObjectsAreSufficient() {
  //just checks the length whatsNewObjects and if less than 80 re runs the loop
  //else adds this the data in the array to firestore and then calls
  if ( whatsNewObjects.lenth > 80 ) {
    //pushes all the data in whatsNewObjects to Firestore and then
    //calls another async function
    await incrementsTheTotalNoItemsAndUnReadItems()
  }
}

async function incrementsTheTotalNoItemsAndUnReadItems() {
  //increments some number fields in firestore by the 
  //length of the WhatsNewObjectsLength
  }

})

所以我希望函数按顺序执行。但我注意到函数的顺序是混合的。如何实现get data()方法中3个函数的顺序执行

【问题讨论】:

  • 应该是for (const task of tasks) await task,你使用for await是错误的。此外,您的示例包含您需要修复的语法错误
  • 感谢Aluan,已解决此问题,问题出在Array中这3个任务的函数体以及您发现的问题
  • Anudeep Ananth@ 很高兴您解决了这个问题。请考虑将解决方案作为答案发布,以使其可见以供将来参考。

标签: typescript firebase async-await google-cloud-functions


【解决方案1】:

所以,我使用的语法实际上是正确的,问题出在 异步函数 getTheLatestInsights(theInterestedPeople: InterestedPerson[]) 在打字稿中使用异步函数有一个陷阱,其中以下语法用于循环遍历异步函数内的数组:

  theInterestedPeople.forEach(async (person) => { 
    //loop through each array to get some data
  }

实际上并没有工作,所以该函数基本上会跳过整个循环(但稍后再执行)。因此,如果我们希望函数等到整个循环完成后再继续执行函数体的其余部分,那么我们必须使用以下语法:

for (const person of theInterestedPeople) {
    //loop through each array to get some data
}

【讨论】:

    【解决方案2】:

    为了确保您的 async/await 您需要使用 Promise 来处理代码流。

    promise 的作用是让你控制执行一系列异步任务,一个接一个地执行。

    Promise 链接示例:

    new Promise(function(resolve, reject) {
    
      setTimeout(() => resolve(1), 1000); // (*)
    
    }).then(function(result) { // (**)
    
      alert(result); // 1
      return result * 2;
    
    }).then(function(result) { // (***)
    
      alert(result); // 2
      return result * 2;
    
    }).then(function(result) {
    
      alert(result); // 4
      return result * 2;
    
    });
    

    请记住,这不是链接承诺的唯一方式。您可以在documentation 中找到有关“Promises 链接”的更多信息。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-02-26
      • 1970-01-01
      • 2021-11-14
      • 1970-01-01
      • 1970-01-01
      • 2018-03-24
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多