简体   繁体   English

js async await function 执行顺序

[英]js async await function execution order

I have node.js server.我有node.js服务器。 And I should store files on specific api.我应该将文件存储在特定的 api 上。 My function for it:我的 function 为它:

exports.bootcampPhotoUpload = asyncHandler(async (req, res, next) => {
  ...
  const fileNames = [];
  files.forEach((item) => {
    item.name = `photo_${bootcamp._id}${path.parse(item.name).ext}`;
    item.mv(`${process.env.FILE_UPLOAD_PATH}/${item.name}`, async err => {
      console.log(item.name); // logs on console second and shows fileName
      fileNames.push(item.name);
    });
  });

  console.log(fileNames); // logs on console firstly and shows []
  const updated = await Bootcamp.findByIdAndUpdate(req.params.id, { photo: fileNames });
  console.log(fileNames); // logs on console third and shows [filenames]
  res.status(200).json({
    success: true,
    data: fileNames
  });
});

And on my model saved:在我的 model 上保存:

{
  photo: []
}

item object: item object:

{ name: 'photo_2020-04-18 14.08.56.jpeg',
  data:
   <Buffer ff d8 ff e0 00 10 4a 46 49 46 00 01 01 01 00 48 00 48 00 00 ff db 00 43 00 04 03 03 04 03 03 04 04 03 04 05 04 04 05 06 0a 07 06 06 06 06 0d 09 0a 08 ... >,
  size: 208920,
  encoding: '7bit',
  tempFilePath: '',
  truncated: false,
  mimetype: 'image/jpeg',
  md5: 'f8714b4e2135c3873c939a9464ea380a',
  mv: [Function: mv]
}

For file upload I'm using express-fileupload .对于文件上传,我使用的是express-fileupload There is problem with async/await executing. async/await执行有问题。 How can I save it correctly?如何正确保存?

Two problems here.这里有两个问题。

  1. Your mv function is async and callback-based, so you cannot use await directly.您的mv function 是异步和基于回调的,因此您不能直接使用 await 。
  2. Even if we turn it to promise-based, await won't work with forEach as we expect.即使我们把它变成基于 Promise 的,await 也不会像我们期望的那样与 forEach 一起工作。

For the first one, we can use the normal for loop.对于第一个,我们可以使用普通的 for 循环。 And for the second one, we can use util.promisify to convert your mv function to promise based.对于第二个,我们可以使用util.promisify将您的mv function 转换为基于 promise。 Check here for doc on util.promisify . 在此处查看有关util.promisify的文档。

Try the below code,试试下面的代码,

const util = require('util');

const fileNames = [];

for (let i = 0; i < files.length; i++) { // 1. for loop here to support await in code block
    const item = files[i];
    item.name = `photo_${bootcamp._id}${path.parse(item.name).ext}`;
    try {
        await util.promisify(item.mv)(`${process.env.FILE_UPLOAD_PATH}/${item.name}`)   // 2. Promisify here so we can await
        console.log(item.name);
        fileNames.push(item.name);
    } catch (err) {
        // handle err
    }
}

console.log(fileNames);

Note: util.promisify could be slower, so it will be better if you find an alternate method/version of mv which already is promise-based.注意: util.promisify可能会更慢,所以如果你找到一个已经是基于 promise 的替代方法/版本的mv会更好。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM