2015-08-28 50 views
1

我的程序如下三种功能,fs.writefile只执行去年功能节点JS

var userId = req.userId; 
    var appId = req.body.appId; 

    var main = 'temp/' + userId + '/templates/' + appId + '/css/main.css'; 

    var color = req.body.color; 
    var font = req.body.font; 
    var fontSize = req.body.fontSize; 

     replaceThemecolor(color); 
     replaceFont(font); 
     replaceFontSize(fontSize); 

    function replaceThemecolor(color) { 
     fs.readFile(main, 'utf-8', function (err, data) { 
      var regex =/(\.made-easy-themeColor\s*{[^}]*color\s*:\s*)([^\n;}]+)([\s*;}])/; 
      var result = data.replace(regex, "$1" + color + "$3"); 
      console.log(color); 
      fs.writeFile(main, result, 'utf-8', function (err) { 
       if (err) return console.log(err); 
      }); 
     }); 
    } 

    function replaceFont(font) { 
     fs.readFile(main, 'utf-8', function (err, data) { 
      var regex =/(\.made-easy-themeFont\s*{[^}]*font-family\s*:\s*)([^\n;}]+)([\s*;}])/; 
      var result = data.replace(regex, "$1" + font + "$3"); 
      console.log(font); 
      fs.writeFile(main, result, 'utf-8', function (err) { 
       if (err) return console.log(err); 
      }); 
         console.log(result); 
     }) 
    } 

    function replaceFontSize(fontSize) { 
     fs.readFile(main, 'utf-8', function (err, data) { 
      var regex =/(\.made-easy-themeFontSize\s*{[^}]*font-size\s*:\s*)([^\n;}]+)([\s*;}])/; 
      var result1 = data.replace(regex, "$1" + fontSize + "em" + "$3"); 
      console.log(fontSize); 
      fs.writeFile(main, result1, 'utf-8', function (err) { 
       if (err) return console.log(err); 
      }); 
     }); 
    } 

在这里只有最后一个函数执行所有的时间,当我执行他们seperately他们的工作很好,但所有功能一次执行时会出现问题。这是fs.writeFile函数的问题吗?我想一起执行这三个函数,有没有办法做到这一点?这里的所有功能在分开执行时都能很好地工作。

+0

使用writeFileSync而不是writeFile来避免同步问题。在这里你正在处理相同的文件,所以问题可能在那里 – binariedMe

+0

不,它不是我的工作 – shamila

回答

1

您的文件功能是异步的。你不能同时运行它们,因为它们会冲突,并且会覆盖另一个的变化。你必须运行一个,然后当它结束时,运行另一个。

或者,甚至更好,只读取一次文件,处理所有更改的数据,然后写入一次。


如果你要连续运行它们,那么你就需要一个回调传递给每个函数当它这样做,那么你知道什么时候开始下一个函数被调用。


但是,我认为更好的解决方案是通过替换指令的数组,只是处理所有的人都在一个读取和文件写入。我将为此编写一个代码示例。

这里有一个办法做到在一个读/写文件的所有更新,并使用承诺,知道什么时候该操作完成:

function updateFile(filename, replacements) { 
    return new Promise(function(resolve, reject) { 
     fs.readFile(filename, 'utf-8', function(err, data) { 
      if (err) { 
       reject(err); 
      } else { 
       // now cycle through and do all the replacements 
       for (var i = 0; i < replacements.length; i++) { 
        data = data.replace(replacements[i].regex, replacements[i].replacer); 
       } 
       fs.writeFile(filename, data, 'utf-8', function(err) { 
        if (err) { 
         reject(err); 
        } else { 
         resolve(); 
        } 
       }); 
      } 
     }); 
    }); 
} 

updateFile(main, [{regex: /(\.made-easy-themeColor\s*{[^}]*color\s*:\s*)([^\n;}]+)([\s*;}])/, replacer: "$1" + color + "$3"}, 
       {regex: /(\.made-easy-themeFont\s*{[^}]*font-family\s*:\s*)([^\n;}]+)([\s*;}])/, replacer: "$1" + font + "$3"}, 
       {regex: /(\.made-easy-themeFontSize\s*{[^}]*font-size\s*:\s*)([^\n;}]+)([\s*;}])/, replacer: "$1" + fontSize + "em$3"}]).then(function() { 
        // update done successfully 
       }, function(err) { 
        // error 
       }); 

有了一些更多的工作,你很可能抽象出来只是来自正则表达式的关键字,所以你只需要传入关键字,但我会把它留给另一个时间。


而这里的一个简化版本:

function updateFile(filename, replacements) { 
    return new Promise(function(resolve, reject) { 
     fs.readFile(filename, 'utf-8', function(err, data) { 
      var regex, replaceStr; 
      if (err) { 
       reject(err); 
      } else { 
       // now cycle through and do all the replacements 
       for (var i = 0; i < replacements.length; i++) { 
        regex = new Regex("(\\" + replacements[i].rule + "\\s*{[^}]*" + replacements[i].target + "\\s*:\\s*)([^\\n;}]+)([\\s*;}])"); 
        replaceStr = "$1" + replacements[i].replacer + "$3"; 
        data = data.replace(regex, replaceStr); 
       } 
       fs.writeFile(filename, data, 'utf-8', function(err) { 
        if (err) { 
         reject(err); 
        } else { 
         resolve(); 
        } 
       }); 
      } 
     }); 
    }); 
} 

updateFile(main, [ 
     {rule: ".made-easy-themeColor", target: "color", replacer: color}, 
     {rule: ".made-easy-themeFont", target: "font-family", replacer: font}, 
     {rule: ".made-easy-themeFontSize", target: "font-size", replacer: fontSize + "em"} 
    ], function() { 
     // update done successfully 
    }, function(err) { 
     // error 
});     

而且,你不必使用承诺在所有如果你不想知道当这一切都完成或能够返回错误(我不会推荐,但代码更简单)。

function updateFile(filename, replacements) { 
    fs.readFile(filename, 'utf-8', function(err, data) { 
     var regex, replaceStr; 
     if (err) { return; } 
     // now cycle through and do all the replacements 
     for (var i = 0; i < replacements.length; i++) { 
      regex = new Regex("(\\" + replacements[i].rule + "\\s*{[^}]*" + replacements[i].target + "\\s*:\\s*)([^\\n;}]+)([\\s*;}])"); 
      replaceStr = "$1" + replacements[i].replacer + "$3"; 
      data = data.replace(regex, replaceStr); 
     } 
     fs.writeFile(filename, data, 'utf-8'); 
    }); 
} 

updateFile(main, [ 
     {rule: ".made-easy-themeColor", target: "color", replacer: color}, 
     {rule: ".made-easy-themeFont", target: "font-family", replacer: font}, 
     {rule: ".made-easy-themeFontSize", target: "font-size", replacer: fontSize + "em"} 
    ], function() { 
     // update done successfully 
    }, function(err) { 
     // error 
});     

注意添加更多替代品是多么容易。您只需在通过updateFile()的数组中添加一行。

+0

答案很好,代码少,非常感谢:) – shamila

1

Node.js本质上是异步的。因此,您正在快速连续执行三个读取操作,然后尝试写入已锁定文件的文件,或者至少在读取文件时未包含写入更改。我会用更像async的系列或瀑布方法来解决这个问题。

var async = require("async"); 
var userId = req.userId; 
var appId = req.body.appId; 

var main = 'temp/' + userId + '/templates/' + appId + '/css/main.css'; 

var color = req.body.color; 
var font = req.body.font; 
var fontSize = req.body.fontSize; 

async.series({ 
    replaceThemecolor: function(callback) { 
     fs.readFile(main, 'utf-8', function(err, data) { 
      var regex = /(\.made-easy-themeColor\s*{[^}]*color\s*:\s*)([^\n;}]+)([\s*;}])/; 
      var result = data.replace(regex, "$1" + color + "$3"); 
      console.log(color); 
      fs.writeFile(main, result, 'utf-8', function(err) { 
       callback(err); 
      }); 
     }); 
    }, 
    replaceFont: function(callback) { 
     fs.readFile(main, 'utf-8', function(err, data) { 
      var regex = /(\.made-easy-themeFont\s*{[^}]*font-family\s*:\s*)([^\n;}]+)([\s*;}])/; 
      var result = data.replace(regex, "$1" + font + "$3"); 
      console.log(font); 
      fs.writeFile(main, result, 'utf-8', function(err) { 
       callback(err); 
      }); 
     }) 
    }, 
    replaceFontSize: function(callback) { 
     fs.readFile(main, 'utf-8', function(err, data) { 
      var regex = /(\.made-easy-themeFontSize\s*{[^}]*font-size\s*:\s*)([^\n;}]+)([\s*;}])/; 
      var result1 = data.replace(regex, "$1" + fontSize + "em" + "$3"); 
      console.log(fontSize); 
      fs.writeFile(main, result1, 'utf-8', function(err) { 
       callback(err); 
      }); 
     }); 
    } 
}, function(err, results) { 
    // results is empty, but now the operation is done. 
}); 
+0

谢谢你的回答对我很好 – shamila

+0

@adithya - 为什么如果读取一次,读取/写入同一文件3次,进行全部三次更改,然后写入一次? – jfriend00

+0

@ jfriend00touché,但是我们不要为了第一个问题发生问题:D – brandonscript