Node.js 将Promise.all()与SequeliseJS一起使用

Node.js 将Promise.all()与SequeliseJS一起使用,node.js,promise,Node.js,Promise,我想检查我的数据库中是否使用了上载文件。所以我想列出“uploads”文件夹中的所有文件,然后与SequelizeJs一起检查该项是否具有正确的属性 我的代码似乎无法正常工作: var promises = []; fs.readdir('./public/uploads', (err, files) => { if (!err) { promises = files.filter(function(file) { if (file !== 'csv' &

我想检查我的数据库中是否使用了上载文件。所以我想列出“uploads”文件夹中的所有文件,然后与SequelizeJs一起检查该项是否具有正确的属性

我的代码似乎无法正常工作:

var promises = [];

fs.readdir('./public/uploads', (err, files) => {
  if (!err) {

    promises = files.filter(function(file) {
      if (file !== 'csv' && file !== '.gitignore') {

        // vérification dans FileModel
        return models.FileModel.findOne({ where: { name: '/uploads/' + file } }).then(function(findedFile) {
          if (!findedFile) {
            return Promise.resolve(file).then(function() {

              // Vérification dans VehiclePhotoModel
              return models.VehiclePhotoModel.findOne({ where: { name: '/uploads/' + file } }).then(function(findedFile) {
                if (!findedFile) {
                  return Promise.resolve(file);
                }
              });
            });
          }
        });
      }
    });
  }
});

Promise.all(promises).then(function(unusedFiles) {
  response.render('file/_checkUnusedFiles', {
    _layoutFile: false,
    unusedFiles: unusedFiles
  });
});
编辑#1:

我把你的代码弄混了,这对我来说不管用,但我还是遇到了一个问题,Promise.resolve()没有返回字符串名文件

const fileModels = [
  { model: models.FileModel, property: 'name' },
  { model: models.VehiclePhotoModel, property: 'name' }
];

function _checkUnusedFiles(request, response) {
  var promises = [],
      files = _.remove(fs.readdirSync('./public/uploads'), function(file) {
        return file !== 'csv' && file !== '.gitignore';
      });

  promises = _.map(files, function(file) {
    return fileModels.map(function(fileModel) {
      var where = {};
      where[fileModel.property] = file;
      return fileModel.model.findOne({ where: where }).then(function(findedItem) {
        if (!findedItem) {
          return Promise.resolve(file);
        }
      });
    });
  });

  Promise.all(promises).then(function(unusedFiles) {
    response.render('optimizer/_checkUnusedFiles', {
      _layoutFile: false,
      unusedFiles: unusedFiles
    });
  });
}

有了上面的代码,您很快就会进入回调地狱,这将导致类似您所提到的问题。总之,问题如下

文件。过滤器
返回

||

摘自文件:

更好的方法是循环,然后执行类似于
promises.append(…)

更好的方法是使用
async
wait
分解代码,以避免回调地狱和类似问题

你真的不需要承诺。在你的情况下,这一切都会变得更加复杂,可能会成为性能瓶颈

像这样的东西应该行得通

const fs = require('fs')
const path = require('path')

// Mocking SequeliseJS (You can remove this and replace in code as well with original models
const modelsMock = {
  FileModel: {
    findOne: (query) => {
      return new Promise((resolve, reject) => {
        // rand will just randomize result between true and false
        let rand = Math.floor(Math.random() * Math.floor(2))
        resolve(rand == 1 ? resolve(true) : resolve(false))
      })
    }
  },

  VehiclePhotoModel: {
    findOne: (query) => {
      return new Promise((resolve, reject) => {
        // rand will just randomize result between true and false
        let rand = Math.floor(Math.random() * Math.floor(2))
        resolve(rand == 1 ? resolve(true) : resolve(false))
      })
    }
  }  
}

run()

async function run() {
  let promises = []
  let existFiles = []
  let doesntExistFiles = []

  // If the goal is to use readdir async then uncomment the following and comment let files = fs.readdirSync('./public/uploads')
  /* 
  const util = require('util')
  const readdir = util.promisify(fs.readdir);
  let files = await readdir('./public/uploads')
  */

  let files = fs.readdirSync('./public/uploads')
  
  // Filter files: (using array.filter is pretty useless to us here since we can't run it async unless we want to promisify it which there are plenty of examples out there, for now we will stick with good old fashion loop)

  for(var i = 0; i < files.length; i++) {
    const file = files[i]
    if(path.extname(file) !== '.csv' && path.extname(file) !== '.gitignore') {
      try {
         let exist = await checkIfFileExist(file, modelsMock)
         exist === true ? existFiles.push(file) : doesntExistFiles.push(file)
      } catch (e) {
         // Handle error here
      }
    }
  }
  
  response.render('file/_checkUnusedFiles', {
      _layoutFile: false,
      unusedFiles: unusedFiles //Note this will break the code as unusedFiles is undefined, I really dont know what is this variable hence I didn't change it but feel free to change it as you see it appropriate.
  });
}

async function checkIfFileExist(file, models){
  let query = `{ where: { name: '/uploads/' + ${file} } }`
  
    try {
       let existInFiles = await models.FileModel.findOne(query)
       if(!existInFiles) {
          let existInVehicle = await models.VehiclePhotoModel.findOne(query)
          existInVehicle ? return true : return false
       } else {
          return true
       }
    }
    catch(e) {
       throw e
    }
  
}
如果不展平
承诺的输出,则
如下所示

promises = 
[
  [ Promise { <pending> }, Promise { <pending> } ],
  [ Promise { <pending> }, Promise { <pending> } ]
]

现在请记住,
unusedFiles
输出可能看起来很奇怪,这是因为并不是每个承诺都能真正解决一些有意义的问题,至少这是您正在映射的内容。

让我理解一下,因此,您正在尝试将文件筛选到数据库中存在的文件,这些文件位于
FileModel
VehiclePhotoModel
中,并且您关心的是先签入
FileModel
,然后签入
VehiclePhotoModel
?你想知道那些不存在的文件名吗?是的,我只需要检查数据库中是否存在文件,然后返回文件夹中使用的文件名。明白了。请检查我的答案,它会解决你的问题。这不是最好的,但它会让你的工作做得很好。我看不出findOne查询对的顺序有什么关系。当然,它们可以并行进行。你的代码对我不起作用,我只是根据你的灵感编辑了我的代码。你能看到我的Promise.resolve()代码中的问题吗?
?在Promise构造函数中执行异步函数是危险的错误处理方式,对于完成任何事情来说也是毫无意义的。它可以是一个
返回现有车辆
。您可能在那里错误地使用了字符串查询?@BenjaminGruenbaum 100%正确。这就是为什么我用
try catch
捕捉它,但你是对的,它在这里没有任何用途,不知道我在想什么。将编辑答案。是的,这个查询应该连接而不是使用字符串。谢谢你指出它们@tonymx227我将查看您的编辑并回复您。与此同时,我更新了我的answer@tonymx227根据我所看到的,您正在映射每个文件的2个承诺,这将使您的
承诺
数组实际上没有承诺,但它将是一个数组,每个值都是2个承诺的数组,因此
承诺。所有(承诺)
都不会做任何事情。我将修复您的问题并编辑我的代码;然而,我不认为当你100%确信你的查询会在其中任何一个中运行两次是一个好的实践。最好先检查,然后再重新检查。请检查我的最新答案。
promises = 
[
  [ Promise { <pending> }, Promise { <pending> } ],
  [ Promise { <pending> }, Promise { <pending> } ]
]
promises = 
[
  Promise { <pending> },
  Promise { <pending> },
  Promise { <pending> },
  Promise { <pending> }
]