1

在下面的代码中,为什么 createFile 回调会触发两次?这只发生在服务器(如下)同时处理两个或多个请求时,而不是只发出一个请求。输出在帖子底部。发出请求的客户端不是浏览器,而是另一个 node.js 脚本遍历目录并向服务器发送带有文件的 http post 请求。请求是这样创建的:

fs.createReadStream(fileName).pipe(httprequest(options, function(error, response, body) { }));
function myRequest(request, response) {
  function writeFile(filePath, request, callback) {
    newFilePath = "/home/pi/upload"+filePath; //filePath looks like this: /home/blah/file.txt, the code below creates this structure under another directory, so newFilePath becomes /home/pi/upload/home/blah/file.txt
    tempFileName = path.basename(filePath)+".temp";
    console.log("Processing "+filePath+"->"+newFilePath+" with tempname " +tempFileName);
    var createFile = request.pipe(fs.createWriteStream(tempFileName));
    createFile.on("finish", function(error) { //Why does it fire the callback twice?
      if(error) {
        throw error;
      } else {
        moveFile(tempFileName, newFilePath, function(error) {
          if(error) {
            throw error;
          } else {
            console.log("OK");
          }
        });
      }
    });
  }

  function moveFile(tempFileName, newFilePath, callback) {
    dirPath = path.dirname(newFilePath);
    fs.stat(dirPath, function(error, stats) { //check if dir exists
      if(error == null) {
        console.log(dirPath+" already exists");
        fs.stat(tempFileName, function(error, stats) { //check if file exists
          if(error == null) {
            console.log("OK, writing "+newFilePath);
            fs.rename(tempFileName, newFilePath, function(error) {
              if(error) { //Error on the second run, because the file has been moved in the first run, shouldn't happen?
                throw error;
              } else {
                var myCB = JSON.stringify({fMove: "OK"});
                callback(myCB);
              }
            });
          } else {
            console.log("File exists");
          }
        });
      }
    });
  }
  writeFile(fileName, request, function() {
    //Do some stuff
  });
  request.on("end", function() {
    //Do other stuff
  }
});

http.createServer(myRequest).listen(8888);

我的脚本的输出

Processing /home/pi/app/temp/client.js->/home/pi/upload/home/pi/app/temp/client.js with tempname client.js.temp
/home/pi/upload/home/pi/app/temp already exists
/home/pi/upload/home/pi/app/temp already exists
OK, Writing /home/pi/upload/home/pi/app/temp/client.js
OK, Writing /home/pi/upload/home/pi/app/temp/client.js

/home/pi/app/server.js:67
            throw error;
                  ^
{"fMove":"OK"}
4

1 回答 1

0

不正确的错误处理使脚本出错。

在 moveFile 函数中,这部分是错误的:

fs.rename(tempFileName, newFilePath, function(error) {
              if(error) {
                throw error;
              } else {
                var myCB = JSON.stringify({fMove: "OK"}); 
                callback(myCB); // <-- Malformatted callback! Should be callback(null, myCB);
              }

这使得 writeFile 的这一部分触发错误并且由于某种原因运行两次:

moveFile(tempFileName, newFilePath, function(error) { //Should be moveFile(tempFileName, newFilePath, function(error, status) {
          if(error) {
            throw error;
          } else {
            console.log("OK");
          }
        });

当我修复我的代码以便它正确处理错误时,它按预期工作!

于 2013-11-04T12:35:13.447 回答