我假设我在诺言方面缺乏一些基本知识。我有一个在AWS Lambda内的流程,该流程下载三个文件,然后生成通过电子邮件发送的输出。
module.exports.test = async (event) => {
var p = download1();
var c = download2();
var h = download3();
await Promise.all([p, c, h]).then(() => {
... bunch of logic manipulating the data
customers.forEach(i => {
buildFile().then(data => {
sendEmail(data).then(response => {
console.log('Email sent successfully');
});
});
});
}, errHandler);
};
buildFile和sendEmail函数均返回Promise,但我从未收到“成功发送电子邮件”消息。它运行代码,但实际上不会在Lambda完成之前返回(至少我认为这是正在发生的事情)。
我的理解是Promise将完成回调,但是现在我想我需要做的事情与在原始Promise.all()中进行下载的方式类似。那是正确的方向吗?
该过程应获取文件,然后循环遍历客户以创建每个文件并通过SES发送。
答案 0 :(得分:6)
您正在寻找
module.exports.test = async (event) => {
var p = download1();
var c = download2();
var h = download3();
try {
await Promise.all([p, c, h]);
// ... bunch of logic manipulating the data
var promises = customers.map(async (i) => {
var data = await buildFile();
var response = await sendEmail(data);
console.log('Email sent successfully');
});
await Promise.all(promises);
} catch(e) {
errHandler(e);
}
};
您的test
函数没有等待您在forEach
循环中创建的承诺,因此lambda在完成所有操作之前就完成了。
答案 1 :(得分:1)
@Bergi的答案是正确的,但是我想稍微扩展一下,并为您提供一些资源来增加或增强您的Promises
知识。我将使用下一个代码段,这有点麻烦,因为我是在Google Chrome
代码段上编写的,因此可以随时将其粘贴并使用它:
(function() {
const promise1 = new Promise(function(resolve, reject) {
setTimeout(function() {
resolve('Replicant');
}, 300);
});
const promise2 = new Promise(function(resolve, reject) {
setTimeout(function() {
resolve('Human?');
}, 300);
});
function buildFile(type) {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve(`${type}`);
}, 300);
});
}
function sendMail(customer, answer) {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve(`Sent test to: ${customer}, he/she is a ${answer}`);
}, 300);
});
}
let customers = ['Rob Batty', 'Rachel', 'Deckard'];
async function myFunc() {
const [a, b, c] = await Promise.all([promise1, promise1, promise2]);
const answers = [a, b, c];
// const promises = customers.map(async (name, index) => {
// const file = await buildFile(answers[index]);
// const mail = await sendMail(name, file);
// console.log(mail);
// });
const promises = customers.map((name, index) => {
buildFile(answers[index])
.then(file => sendMail(name, file))
.then(sent => console.log(sent))
// If you're going to use Promises this is important! :D
.catch(err => console.log(err))
});
const [m1, m2, m3] = await Promise.all(promises);
console.log(m1, m2, m3);
}
myFunc();
})()
正如答案中指出的那样,问题与forEach
的使用有关,为什么?好吧,仅因为您是在asynchronous
类型的方法上执行synchronous
代码,所以相处的不是很好:),因此,解决方案是创建一个Array
的方法Promises
,就像Factory
。在map
函数之后,Promises
是Pending
也不是Fullfiled
或Rejected
,这是在您调用Promise.all()
方法时等待它们的结果以及他们为您提供值或在您的用例中,生成文件,然后将电子邮件发送给用户。希望这有助于您更好地了解Promises
的工作方式。最后,我将留下两个非常重要的链接,至少对我而言,这在一定程度上帮助了Promises
。干杯,辛辣的。