等待回调在控制器中返回

时间:2019-07-29 15:33:35

标签: javascript node.js sails.js

我想上传一些文件,将它们添加到数据库中并返回新对象的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而无需等待结果。

1 个答案:

答案 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));
        });
    });
}

我希望这会有所帮助。