在下面的函数中,我尝试返回文件,但是在搜索文件时返回未定义,它返回未定义。在执行搜索并获取S3对象的地方,并准备对象数组以进一步发送电子邮件。
const send_email = async(data) => {
try {
const data_attachment = await get_S3_files(batch_key);
console.log(data_attachment)
} catch (error) {
console.log(error)
}
}
const get_S3_files = (data) => {
return new Promise((resolve, reject) => {
var params = {
Bucket: S3_bucket,
Delimiter: '',
Prefix: `${data}/`
}
var files = []
s3.listObjects(params, function (err, data) {
if (err) throw err;
if (data.Contents.length) {
for (const row of data.Contents) {
await s3.getObject({ Bucket: 'name', Key: row.Key }, function (err, data) {
if (err) {
console.log('S3 Get Object Error', err)
reject(err)
} else {
console.log(data)
files.push({
filename: data.Body,
content: data.Metadata.file_name,
})
}
})
}
}
});
resolve(files);
})
}
编辑-
有人可以在这里帮助吗?我在做什么错了?
答案 0 :(得分:0)
您从错误的地方回来。您的return语句位于s3.listObjects
函数内部。 return files;
应该在关闭函数之前在下面一行。但是,它仍然无法正常工作。您必须保证该功能。
const get_S3_files = (data) => {
return new Promise((resolve, reject) => {
var params = {
Bucket: 'name',
Delimiter: '',
Prefix: `${data}/`
}
var files = []
s3.listObjects(params, async function (err, data) {
if (err) throw err;
if (data.Contents.length) {
for (const row of data.Contents) {
await s3.getObject({ Bucket: 'name', Key: row.Key }, function (err, data) {
if (err) {
console.log('S3 Get Object Error', err)
reject(err)
} else {
console.log(data)
files.push({
filename: data.Body,
content: data.Metadata.file_name,
})
}
})
}
}
resolve(files);
});
})
}
答案 1 :(得分:0)
问题出在竞争状况上。它甚至在等待数组填充之前就返回。
我认为此解决方案可能有效。
const send_email = async (data) => {
try {
const data_attachment = await get_S3_files(batch_key);
console.log(data_attachment);
} catch (error) {
console.log(error);
}
};
const get_S3_files = (batch_key) => {
return new Promise((resolve, reject) => {
var params = {
Bucket: S3_bucket,
Delimiter: "",
Prefix: `${batch_key}/`,
};
s3.listObjects(params, async function (err, data) {
var files = [];
if (err) throw err;
if (data.Contents.length) {
await Promise.all(
data.Contents.map((row) => {
return new Promise((resolve, reject) => {
s3.getObject({ Bucket: S3_bucket, Key: row.Key }, (err, data) => {
if (err) return reject(err);
files.push({
filename: data.Body,
content: data.Metadata.file_name,
});
return resolve(data);
});
});
})
);
}
return resolve(files);
});
});
};
答案 2 :(得分:0)
下面的代码片段不一定能解决原始问题,但是如果OP开放以对其代码进行一些大的更改,那么我认为该解决方案将在不影响原始功能的情况下完美地工作。
const get_S3_files = async (data) => {
var params = {
Bucket: 'name',
Delimiter: '',
Prefix: `${data}/`
}
var files = []
await s3.listObjects(params, async function (err, data) {
if (err) throw err;
if (data.Contents.length) {
for (const row of data.Contents) {
try {
const dataContent = await s3.getObject({ Bucket: 'name', Key: row.Key }).promise();
files.push({
filename: dataContent.Body,
content: dataContent.Metadata.file_name,
})
} catch(err) {
console.log('S3 Get Object Error', err);
}
}
}
return files;
});
}
在任何地方使用回调都会使代码不可读。我建议您使用promise()和s3 sdk的方法将响应转换为承诺。
类似地,您可以将listObjects
方法转换为Promise。它将使代码更具可读性。
注意:我从代码末尾添加了一些变量,请确保根据您的代码上下文对其进行更改。