我想上传一些文件,将它们添加到数据库中并返回新对象的ID。
fn: async function (inputs) {
let docIds = []
let settings = {...}
await inputs.filesToUpload.upload(settings, async (err, files) => {
if (err)
throw {'invalid': 'The provided data is invalid.'}
for (let i = 0; i < files.length; i += 1) {
let newDocument = await Document.create({
name: file.filename
}).fetch()
docIds.push(newDocument.id)
}
})
return {
ids: docIds
}
})
不幸的是,控制器不等待在数据库中创建对象,而是立即返回{ids:[]},只有这样才能上载文档并创建对象。我尝试将id用作回调和promise,但控制器始终执行return而无需等待结果。
答案 0 :(得分:4)
inputs.filesToUpload.upload
正在做一个总是异步的回调。
带有回调的函数之前的async关键字不能使其等待。
异步仅在函数返回承诺时有效
检查以下代码,其中我已在单独的函数中提取了上传流程,该函数返回了诺言
然后您可以等待这个诺言并获取生成的ID。
async function test(inputs) {
const docIds = await upload(inputs, {});
return { ids: docIds };
}
function upload(inputs, settings) {
return new Promise((resolve, reject) => {
const ids = [];
inputs.filesToUpload.upload(settings, async (err, files) => {
if (err) {
return reject({ 'invalid': 'The provided data is invalid.' });
}
for (let i = 0; i < files.length; i += 1) {
let newDocument = await Document.create({ name: file.filename }).fetch();
ids.push(newDocument.id);
}
resolve(ids);
});
});
}
请注意,上面的功能只是在澄清诺言的使用。
可以通过多种方式来实现,特别是如果我们要对其进行优化。
编辑
例如,Promise.all可用于优化顺序(如果订单无关紧要),例如
function upload(inputs, settings) {
return new Promise((resolve, reject) => {
const ids = [];
inputs.filesToUpload.upload(settings, async (err, files) => {
if (err) {
return reject({ 'invalid': 'The provided data is invalid.' });
}
const newDocuments = await Promise.all(files.map(file =>
Document.create({ name: file.filename }).fetch())
);
resolve(newDocuments.map(newDocument => newDocument.id));
});
});
}
我希望这会有所帮助。