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

Nested for loop in nodejs seems to be running asynchronously

所以我有两个 for 循环,一个嵌套在另一个循环中,但它们 return 的结果似乎是 运行 宁第一个循环和 return 其结果比嵌套循环。我怎样才能使它成为 运行 同步行为? 例如,所有的 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 做同样的事情。

希望这对您有所帮助。