Javascript nodejs中的嵌套for循环似乎是异步运行的

Javascript nodejs中的嵌套for循环似乎是异步运行的,javascript,node.js,amazon-web-services,aws-lambda,amazon-sns,Javascript,Node.js,Amazon Web Services,Aws Lambda,Amazon Sns,我有两个for循环,其中一个嵌套在另一个循环中,但是它们返回的结果似乎是运行第一个循环,并且返回的结果比嵌套的循环要多。如何使其以同步行为运行? 例如,所有topicData都打印在一行中,而不是打印一个topicData并转到嵌套的For循环。 我不确定这是否是实现异步等待的正确方法。任何指点都将不胜感激。谢谢 exports.create = (event, context, callback) => { var topicTimestamp = ""; var endpoi

我有两个for循环,其中一个嵌套在另一个循环中,但是它们返回的结果似乎是运行第一个循环,并且返回的结果比嵌套的循环要多。如何使其以同步行为运行? 例如,所有topicData都打印在一行中,而不是打印一个topicData并转到嵌套的For循环。 我不确定这是否是实现异步等待的正确方法。任何指点都将不胜感激。谢谢

exports.create = (event, context, callback) => {

  var topicTimestamp = "";
  var endpoint = "";

  sns.listTopics(async function(err, data) {
    if (err) {
      console.log(err, err.stack);
    } else {
      console.log(data);
      for (var topic in data.Topics){ //first loop
        //var topicData = "";
        //retrieve each topic and append to topicList if it is lakeview topic
        var topicData =  await data.Topics[topic].TopicArn;
        topicTimestamp = topicData.slice(22, 34); //get only the topic createdAt

        var params = {
          TopicArn: topicData //topicData
        };
        console.log("SUBS per" + params.TopicArn);

        //retrieve subscriptions attached to each topic
        sns.listSubscriptionsByTopic(params, async function(err, subscriptionData){
          console.log(subscriptionData);
          //console.log("SUBS per" + params.TopicArn);
          if (err) {
            console.log(err, err.stack); // an error occurred
          } else  {
            var endpointList = [];
            for (var sub in subscriptionData.Subscriptions) { //nested loop

              endpoint = await subscriptionData.Subscriptions[sub].Endpoint;

              console.log("ENDPOINT:: " + endpoint);
              endpointList.push(endpoint);
            }
          } // end of else listSub

          //put topic info into table
          var topicsParams = {
            TableName: tableName,
            Item: {
              id: uuidv4(),
              createdAt: timestamp,
              topicCreatedAt: topicTimestamp,
              topic: topicData,
              phoneNumbers: endpointList
            },
          };

          endpointList = [];  //reset to empty array

          dynamoDb.put(topicsParams, (error) => {...}

这里有两个问题

  • 当您有可用的promise方法时,您正在尝试在循环中执行回调样式的代码
  • 您还可以使用
    promise.all并行地完成任务
  • 由于回调风格,代码非常复杂
  • 您正在不需要的地方等待。例如在回调函数中
你可以试着用这种方法

exports.create = async (event, context, callback) => {

  try {
    let topicTimestamp = "";
    let endpoint = "";
    const data = await sns.listTopics().promise();
    // eslint-disable-next-line guard-for-in
    for (const topic in data.Topics) { // first loop
    // var topicData = "";
    // retrieve each topic and append to topicList if it is lakeview topic
      const topicData = data.Topics[topic].TopicArn;
      topicTimestamp = topicData.slice(22, 34); // get only the topic createdAt

      const params = {
        "TopicArn": topicData // topicData
      };
      console.log(`SUBS per${ params.TopicArn}`);

      const subscriptionData = await sns.listSubscriptionsByTopic(params).promise();
      const endpointList = [];
      // eslint-disable-next-line guard-for-in
      for (const sub in subscriptionData.Subscriptions) { // nested loop
        endpoint = subscriptionData.Subscriptions[sub].Endpoint;
        console.log(`ENDPOINT:: ${ endpoint}`);
        endpointList.push(endpoint);
      }

      // put topic info into table
      const topicsParams = {
        "TableName": tableName,
        "Item": {
          "id": uuidv4(),
          "createdAt": timestamp,
          "topicCreatedAt": topicTimestamp,
          "topic": topicData,
          "phoneNumbers": endpointList
        }
      };

      // Similarly use dynamodb .promise functions here
    }
  } catch (Err) {
    console.log(Err);
  }
};

默认情况下,aws sdk支持回调样式。要将它们转换为promise,您需要在末尾添加
.promise()

目前,这个示例使用for循环,但是您也可以使用
Promise.all
来做同样的事情

希望这有帮助

对所有异步操作使用承诺接口(如果承诺接口不存在,则创建一个承诺包装器),并对这些承诺使用
wait
。这将允许您对带有异步操作的
循环进行排序。它还将使错误处理变得更干净(您根本没有真正做好这项工作)。