循环内有异步调用时如何保持代码同步

时间:2019-02-07 23:57:35

标签: javascript node.js amazon-web-services asynchronous

我正在循环内填充一个数组,循环结束后我需要完整的数组。

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

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次,这不是我想要的。

2 个答案:

答案 0 :(得分:0)

我相信您可以保证将它链接起来,以确保在进行下链之前,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

}

希望这会有所帮助!

答案 1 :(得分:0)

您可以将Promise.all用于您的问题。请参阅Promise.all()上的文档。

const available_functions = [];

lambda.listFunctions({}).promise()
    .then((data) => {
        const promises = []; // Collect promises

        data.Functions.forEach(func => {
            promises.push(lambda.listTags({ Resource: func.FunctionArn }).promise()
                .then((data) => {
                    available_functions.push(func.FunctionName)
                    return Promise.resolve(available_functions);
                })
            );
        });

        Promise.all(promises)
            .then(results => {
                    console.log(available_functions)
                // or
                    console.log(results[results.length - 1]);
            });
    });