Node.js 在forEach循环中处理承诺
我正在尝试运行一系列任务。每个任务都是动态的,可以遵循不同的规则。这将在AWS Lambda上执行 我有一个JSON数组。它有一个主体,其中包含任务名称,并且还具有属性 我需要动态加载一个javascript文件,文件名在正文中。 我需要等待,直到任务完成。或者它失败了(不管在哪里)。如果失败发生,我将需要在forEach循环中的当前记录中写入该数据 我有一个老问题,我的forEach首先完成,而不用等待任务完成。 这是forEach循环:Node.js 在forEach循环中处理承诺,node.js,promise,aws-lambda,Node.js,Promise,Aws Lambda,我正在尝试运行一系列任务。每个任务都是动态的,可以遵循不同的规则。这将在AWS Lambda上执行 我有一个JSON数组。它有一个主体,其中包含任务名称,并且还具有属性 我需要动态加载一个javascript文件,文件名在正文中。 我需要等待,直到任务完成。或者它失败了(不管在哪里)。如果失败发生,我将需要在forEach循环中的当前记录中写入该数据 我有一个老问题,我的forEach首先完成,而不用等待任务完成。 这是forEach循环: const jobLoader = require('
const jobLoader = require('./Helpers/jobLoader');
event.Records.forEach(record => {
const { body: jobName } = record;
const { messageAttributes } = record;
const job = jobLoader.loadJob(jobName);
job.runJob(messageAttributes).then(res => {
console.log('Show results');
return; // resume another record from forEach
}).catch(err => {
record.failed = true;
record.failureMessage = err.message;
console.log('I errored');
});
console.log('All Done');
});
问题是打印消息全部完成,然后打印消息显示结果。我从数据库中获取执行结果
这是加载任务的文件:
exports.loadJob = (jobName) => {
const job = require(`../Tasks/${jobName}`);
return job;
};
这是包含实际任务的文件:
const mySqlConnector=require('../Storage/mySql')
这就是mySql连接器本身:
const mysql=require('promise-mysql')
任务文件可以有任意数量的需要完成的内容,当我开始添加任务时,这些内容会有所不同。
我需要job.runJob完成,或者它捕获错误,无论它来自何处,所以我可以继续使用forEach
我尝试过使用map之类的工具,但最终的结果总是一样的
我做错了什么?你可以使用
承诺。所有方法:
const promises = event.Records.map(record => {
const { body: jobName } = record;
const { messageAttributes } = record;
const job = jobLoader.loadJob(jobName);
return job.runJob(messageAttributes).then(res => {
console.log('Show results', res);
}).catch(err => {
record.failed = true;
record.failureMessage = err.message;
console.log('I errored');
throw new Error('Your error !');
});
});
try {
const results = await Promise.all(promises);
console.log('All done');
} catch (e) {
console.log('Something has an error', e);
}
别忘了让你的函数异步 我设法解决了这个问题,但仍然保留了执行的细节:
大概是这样的:
for (let prop in event.Records){
const { body: jobName } = event.Records[prop];
const { messageAttributes } = event.Records[prop];
const job = jobLoader.loadJob(jobName);
await job.runJob(messageAttributes).then(res => {
console.log('Show results', res);
}).catch(err => {
event.Records[prop].failed = true;
event.Records[prop].failed = err.message;
console.log('I errored');
});
}
我现在已经按预期的顺序工作了。但是数据库中的错误,由于某种原因,不会在catch块中传播。是的,这是因为你必须在catch块中抛出一个错误。对不起,我认为这是有意义的。但我永远不会在那个街区结束。我在mysql连接器中发现了错误,但它不会传播。在处理程序中,您必须在catch语句中抛出错误。有没有一种方法可以做到这一点?原因是我丢失了事件出错的信息。最后,我希望有一个出错事件的列表,这样我就可以手动将它们发送到死SQS
const promises = event.Records.map(record => {
const { body: jobName } = record;
const { messageAttributes } = record;
const job = jobLoader.loadJob(jobName);
return job.runJob(messageAttributes).then(res => {
console.log('Show results', res);
}).catch(err => {
record.failed = true;
record.failureMessage = err.message;
console.log('I errored');
throw new Error('Your error !');
});
});
try {
const results = await Promise.all(promises);
console.log('All done');
} catch (e) {
console.log('Something has an error', e);
}
for (let prop in event.Records){
const { body: jobName } = event.Records[prop];
const { messageAttributes } = event.Records[prop];
const job = jobLoader.loadJob(jobName);
await job.runJob(messageAttributes).then(res => {
console.log('Show results', res);
}).catch(err => {
event.Records[prop].failed = true;
event.Records[prop].failed = err.message;
console.log('I errored');
});
}