2015-08-28 51 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