代码之家  ›  专栏  ›  技术社区  ›  Nop0x

节点。js忽略使用express构建awaitZip

  •  2
  • Nop0x  · 技术社区  · 6 年前

    我想用mongoose从我们的mongodb数据库中获取gridfs中的图标PNG。然后,这些图标应按特定路线进行压缩和服务。

    我当前的代码如下:

    var zip = require("node-native-zip");
    async function getZipFile() {
        //get the events out of the DB
        db.Category.find({}).populate('icons.file').exec(async function (err, cats) {
            if (err) {
                //oh oh something went wrong, better pass the error along
                return ({
                        "success": "false",
                        message: err
                    });
            }
            else {
                //all good, build the message and return
                try {
                    const result = await buildZip(cats);
                    return ({
                        "success": "true",
                        message: result
                    });
                }
                catch (err) {
                    console.log("ZIP Build Failed")
                }
            }
        });
    }
    async function buildZip(cats) {
        let archive = new zip();
        for (let i = 0; i < cats.length; i++) {
            cats[i].icons.forEach(function (icon) {
                if (icon.size === "3x") {
                    db.Attachment.readById(icon.file._id, function (err, buffer) {
                        if (err)
                            return;
                        archive.add(cats[i]._id + ".png", buffer);
                    });
                }
            });
            //return when everything is done
            if (i === cats.length - 1) {
                return archive.toBuffer();
            }
        }
    }
    module.exports =
        {
            run: getZipFile
        };
    

    我不想在运行时之前构建zip,因为我想根据类别ID重命名图标。我尝试使用异步/等待结构,但在构建zip文件之前就返回了回调。

    我用调用函数

        case 'categoryZip':
            categoryHelper.getZipFile.run().then((result) => {
                callback(result);
            });
            break;
    

    这应该(据我所知)在压缩完成后触发回调,但我认为我缺少了一些必要的东西。

    1 回复  |  直到 6 年前
        1
  •  2
  •   Patrick Roberts Benjamin Gruenbaum    6 年前

    我将您的两个回调方法包装到promises中,并使用 Promise.all() 由于它们彼此不依赖,并且我假设它们不需要在zip文件中按任何特定顺序排列:

    async function getZipFile() {
      //get the events out of the DB
      return new Promise((resolve, reject) => {
        db.Category.find({}).populate('icons.file').exec(async function(err, cats) {
          if (err) {
            //oh oh something went wrong, better pass the error along
            reject({
              success: false,
              message: err
            });
          } else {
            //all good, build the message and return
            try {
              const result = await buildZip(cats);
    
              resolve({
                success: true,
                message: result
              });
            } catch (err) {
              console.log("ZIP Build Failed")
              reject({
                success: false,
                message: err
              });
            }
          }
        });
      });
    }
    
    async function buildZip(cats) {
      let archive = new zip();
    
      await Promise.all(
        cats.map(cat => Promise.all(cat.icons
          .filter(icon => icon.size === '3x')
          .map(icon => new Promise((resolve, reject) => {
            db.Attachment.readById(icon.file._id, function(err, buffer) {
              if (err) return reject(err);
              archive.add(cat._id + ".png", buffer);
              resolve();
            });
          }))
        ))
      );
    
      return archive.toBuffer()
    }