上传多个文件时出现异步问题

时间:2017-08-23 13:58:22

标签: javascript node.js mongodb express gridfs

您好我正在尝试上传多个文件,文件写入是正确的。但是我想将文件移动到mongo grid fs中,第一个文件只是正常移动文件的其余部分没有移动到网格fs而且也没有取消链接。

这是我的代码:

for (var i = 0; i < files.length; i++) {
    (function(i) {
        var singleFile = files[i];
        var fileData = JSON.parse(files[i].name);
        var fileName = fileData.fileName;
        var fileType = files[i].type;
        var uniqId = fileData.attachmentId;
        var targetPath = "./attachments/" + uniqId;
        var tmp_path = files[i].path;

    console.log("uniqId : " + uniqId);
    //uploadFile(tmp_path,targetPath,fileName,uniqId,fileType);

    fs.readFile(tmp_path, function(err, data) {
        fs.writeFile(targetPath, data, function(err) {
            if (!err) {
                mongoose.connect(configSettings.mongodb.ip, configSettings.mongodb.databasename, configSettings.mongodb.port, function(err, succ) {
                    var id = new ObjectID(uniqId);
                    new GridStore(mongoose.connection.db, id, fileName, 'w', {
                        'content_type': 'application/octet-stream'
                    }).open(function(err, gs) {
                        gs.writeFile(targetPath, function(err) {
                            if (err) {
                                console.log("err");
                            }
                            gs.close(function(err) {
                                console.log("success");
                                fs.unlink("./attachments/" + uniqId, function(err) {
                                    console.log("err : " + err);
                                    console.log(uniqId + ' ::successfully deleted ');
                                });
                                mongoose.connection.close();
                            });
                        });
                    });
                });
            }
        });
    });
   })(i);
}

    res.send("success");

这个我尝试过闭包功能,即使我已尝试创建单独的功能,但同样的结果来了(只插入和取消链接一个文件)。

在这种情况下我需要做什么来将所有文件存储在gridfs中并从临时文件夹中取消链接?

3 个答案:

答案 0 :(得分:1)

这是我的猜测。由于你的调用被推迟到以后,你的函数结束了,文件列表可能被Node或其他东西删除了,你可以在这里看到一个简化的例子:

let myList = [1, 2, 3, 4, 5];

function doWork(list) {
  console.log('Start of function');
  
  for (let i = 0; i < list.length; i++) {
    (function(i) {
      setTimeout(function() {
        console.log('Working on index', i);
        console.log('list[i] :', list[i]);
      }, 100);
    })(i);
  }

  console.log('End of function');
}

doWork(myList);

myList[4] = null;

解决方案是将文件(或列表/索引对)本身包含起来,以使其在您的上下文中保持活动状态:

let myList = [1, 2, 3, 4, 5];

function doWork(list) {
  console.log('Start of function');
  
  for (let i = 0; i < list.length; i++) {
    (function(num) {
      setTimeout(function() {
        console.log('Num :', num);
      }, 100);
    })(list[i]);
  }

  console.log('End of function');
}

doWork(myList);

myList[4] = null;

答案 1 :(得分:1)

实际上问题在于gridFs连接,文件在内部循环上传,网格连接正在写入第一个文件并且循环继续并行。一旦从gridfs开始连接,它应该在插入另一个文件之前关闭,并且必须在下次正确重新连接。

以下是工作代码检查:

\b  Backspace (ascii code 08)
\f  Form feed (ascii code 0C)
\n  New line
\r  Carriage return
\t  Tab
\"  Double quote
\\  Backslash character

使用此代码,我们可以将多个文件插入mongo gridFs .. 希望这有帮助!

答案 2 :(得分:0)

简短回答在这里学习如何在循环内部实现异步功能

(function loop(i) {
if(i==4) return
setTimeout(function() {
  console.log('Working on index', i);
  loop(++i)
 }, 1000);
})(0);

TL; DR https://mongodb.github.io/node-mongodb-native/api-generated/gridstore.html