首页 > 解决方案 > 当循环内有异步调用时如何保持代码同步

问题描述

我正在循环内填充一个数组,循环完成时我需要完整的数组。

我已经尝试通过承诺或使用计数器来处理所有事情,但我似乎无法弄清楚这里的诀窍。

lambda.listFunctions({}).promise()
    .then((data) => {
        data.Functions.forEach(func => {
            lambda.listTags({ Resource: func.FunctionArn }).promise()
                .then((data) => {
                    if ("Edge" in data.Tags) {
                        available_functions.push(func.FunctionName)
                    }
                })
        });
          console.log(available_functions)
    })

available_functions 总是空的,除非我在每个 foreach 循环结束时控制台记录它,然后我让它返回 18 次,这不是我想要的。

标签: javascriptnode.jsamazon-web-servicesasynchronous

解决方案


我相信你可以承诺它链它以确保在then完成链之前的所有操作都在完成范围内。

lambda.listFunctions({}).promise()
  .then(data => {
    const { Functions } = data;

    // I converted this from forEach to for of
    for (const func of Functions) {
      lambda.listTags({ Resource: func.FunctionArn }).promise()
        .then(data => {
          if ("Edge" in data.Tags) {
            available_functions.push(func.FunctionName)
          }
        })
    }
  // also you can promise chain it if available_functions is within scope
  })
  .then(() => console.log(available_functions))

或者更清洁的async await方式看起来像......

async fn() {
  const available_functions = [];

  const { Functions } = await lambda.listFunctions({}).promise();

  for (const func of Functions) {
    const tags = await lambda.listTags({ Resource: func.FunctionArn }).promise();

    if ("Edge" in tags) {
      available_functions.push(func.FunctionName)
    }

  }

  return available_functions

}

希望这可以帮助!


推荐阅读