Javascript nodejs中的嵌套for循环似乎是异步运行的
我有两个for循环,其中一个嵌套在另一个循环中,但是它们返回的结果似乎是运行第一个循环,并且返回的结果比嵌套的循环要多。如何使其以同步行为运行? 例如,所有topicData都打印在一行中,而不是打印一个topicData并转到嵌套的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
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
。这将允许您对带有异步操作的循环进行排序。它还将使错误处理变得更干净(您根本没有真正做好这项工作)。