首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >节点js异步&等待函数-强制功能完成?

节点js异步&等待函数-强制功能完成?
EN

Stack Overflow用户
提问于 2021-02-19 09:45:15
回答 2查看 256关注 0票数 0

我试图上传一个图片使用一个组件(summernote)的角度形式。

我将uploadImagePath端点配置为将映像提交到nodejs后端,但在我的代码中,outputFileName字段是空的。

如何确保函数完成?

代码语言:javascript
复制
async uploadFile(req) {

    var multiparty = require('multiparty');
    var form = new multiparty.Form();
    
    let outputFileName = '';

    try {

        form.parse(req, function(err, fields, files) {  
            var imgArray = files.image;

            for (var i = 0; i < imgArray.length; i++) {
                
                var singleImg = imgArray[i];
                outputFileName = singleImg.originalFilename;
                
                fs.readFile(singleImg.path , function(err,data) {
                    fs.writeFile('./public/images/'+outputFileName,data, function(err) {
                        if (err) console.log('ERRRRRR!! :'+err);
                        console.log('Fitxer: ' + outputFileName);
                    })
                })       
            }
        });
    } 
    catch (ex) {
        throw ex;
    }

    return { error: false, outputFileName: outputFileName, msg: "File uploaded!" };
}
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2021-02-19 10:01:23

您不应该直接调用接受async函数中回调的函数。这就是为什么尝试捕捉错误的机会较小的原因。相反,返回一个Promise来处理该错误。

代码语言:javascript
复制
function uploadFile(req) {
  return new Promise((resolve, reject) => {
    const multiparty = require('multiparty')
    const form = new multiparty.Form()
    let outputFileName = ''
    form.parse(req, function (err, fields, files) {
      if (err) {
        reject(err)
        return
      }
      const imgArray = files.image

      // You should not call function that accepts a callback in for loop
      // Lets assumed imageArray has only one element.
      // for (let i = 0; i < imgArray.length; i++) {
        const singleImg = imgArray[0 /* i */]
        outputFileName = singleImg.originalFilename
        fs.readFile(singleImg.path, function (err, data) {
          if (err) {
            reject(err)
            return
          }
          fs.writeFile('./public/images/' + outputFileName, data, function (err) {
            if (err) {
              reject(err)
              return
            }
            console.log('Fitxer: ' + outputFileName)
            resolve({
              error: false,
              outputFileName: outputFileName,
              msg: "File uploaded!"
            })
          })
        })
      // }
    });
  })
}

但是正如您所看到的,上面的代码是混乱的,并且for-循环不起作用。要解决这个问题,我们应该使uploadFile异步,其中不能使用回调。

如果可能,async函数应该调用返回Promise的另一个函数,这样await关键字可以帮助简化代码并处理抛出的错误。为此,编写一个新函数来实现form.parse异步,并替换支持返回Promise的东西的fs,例如fs.Promise APIfs-extra package

代码语言:javascript
复制
const fs = require('fs-extra')
const multiparty = require('multiparty')

function parseForm(req) {
  return new Promise((resolve, reject) => {
    const form = new multiparty.Form()
    form.parse(req, function (err, fields, files) {
      if (err) reject(err)
      else resolve(files)
    })
  })
}

async function uploadFile(req) {
  let outputFileName = ''
  const files = await parseForm(req)
  const imgArray = files.image

  // Now we can use for loop
  for (let i = 0; i < imgArray.length; i++) {
    const singleImg = imgArray[i]
    outputFileName = singleImg.originalFilename
    const data = await fs.readFile(singleImg.path)
    await fs.writeFile('./public/images/' + outputFileName, data)
    console.log('Fitxer: ' + outputFileName)
  }
  return {
    error: false,
    outputFileName: outputFileName,
    msg: "File uploaded!"
  }
}

不过,您的代码中仍然存在一些问题。outputFileName被分配了不止一次,这使得您的目标很难理解。由于这个原因,我不能重写您所期望的代码。

顺便说一句,应该考虑到更多的条件。我不想多谈这件事。

  • 建议not use var keyword声明局部变量。在for-循环中使用constlet关键字使用await关键字,除非要逐个迭代元素。
票数 2
EN

Stack Overflow用户

发布于 2021-02-19 10:01:34

最简单的方法是制作一个助手函数,使nodestyle fn返回一个承诺,然后使用它。

代码语言:javascript
复制
function parseMultiparty(req) {
  return new Promise((resolve, reject) => {
    var form = new multiparty.Form();
    form.parse(req, function(err, fields, files) { 
      if(err) reject(err) else resolve([fields, files])
    })

  })
}
代码语言:javascript
复制
async uploadFile(req) {

    var multiparty = require('multiparty');
    var form = new multiparty.Form();
    
    let outputFileName = '';

    try {
        const [fields, files] = await parseMultiparty(req)
          var imgArray = files.image;

          for (var i = 0; i < imgArray.length; i++) {
              
              var singleImg = imgArray[i];
              outputFileName = singleImg.originalFilename;
              
              const data = await fs.promises.readFile(singleImg.path)
              console.log('Fitxer: ' + outputFileName);
              try {
                await fs.promises.writeFile('./public/images/'+outputFileName,data)
              } catch(err) { console.log('ERRRRRR!! :'+err);}
          }
    } 
    catch (ex) {
        throw ex;
    }

    return { error: false, outputFileName: outputFileName, msg: "File uploaded!" };
}
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/66275184

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档