2015-10-09 155 views
0

在我的應用程序中,我試圖讀取文件,然後將文件的內容寫入另一個文件。在Node.JS中使用藍鳥承諾

我已經使用藍鳥承諾來做到這一點。我需要幫助來確認我對使用承諾的理解在我的實施中是正確的。

,我已經是問題,

  1. 在我的例子,我第一次讀文件,那麼一旦文件讀取的文件,我寫的內容爲在明年的另一個文件」。然後'阻止。一旦內容寫入文件,我需要記錄一條消息。我已經將它包含在第二個「.then」塊中。我需要知道我的理解對承諾是否正確。第二個'.then'塊會作爲writefile語句的回調函數嗎?

  2. 我需要編寫更有意義的日誌消息。如果在讀取文件和寫入文件時發生錯誤,則會顯示不同的錯誤消息。我怎樣才能用catch塊來做到這一點?

在此先感謝!

代碼示例如下。

var Promise = require("bluebird"); 
var fs = Promise.promisifyAll(require("fs")); 
var logger = require("./logger.js") 
var projectJSON = require("../project.json"); 

var harPath = projectJSON.project.harfile.location; 
var harFileNames = projectJSON.project.transactions.transactionsName; 
var harFilePath; 
var harFiles = {}; 
var writeFilePath = "../temp/" 


harFileNames.forEach(function(harFileName){ 
    harFilePath = harPath + "/" + harFileName + ".har"; 

    fs.readFileAsync(harFilePath, "utf-8") 
     .then(function(data){ 
      fs.writeFile(writeFilePath + harFileName + ".json", data); 
      test = data; 

     }) 
     .then(function(){ 
      console.log("data written successfully: "); 

     }) 
     .catch(function(err){ 
      logger.error("error", "Error reading har files from location!"); 

     }); 

}); 

回答

1

如果要單獨捕獲每個錯誤,那麼你就可以立即在每次操作後把一個錯誤處理程序,因此您可以直接捕捉特定的錯誤。

然後,要傳播錯誤,您可以重新拋出錯誤值。

然後,你想切換到fs.writeFileAsync(),所以一切都是異步的,並使用承諾。

然後,您需要從fs.writeFileAsync()返回承諾。

var Promise = require("bluebird"); 
var fs = Promise.promisifyAll(require("fs")); 
var logger = require("./logger.js") 
var projectJSON = require("../project.json"); 

var harPath = projectJSON.project.harfile.location; 
var harFileNames = projectJSON.project.transactions.transactionsName; 
var harFilePath; 
var harFiles = {}; 
var writeFilePath = "../temp/" 


harFileNames.forEach(function(harFileName){ 
    harFilePath = harPath + "/" + harFileName + ".har"; 

    fs.readFileAsync(harFilePath, "utf-8") 
     .then(function(data){ 
      harFiles[JSON.parse(data).log.pages[0].id] = JSON.parse(data); 
      return data; 
     }).catch(err) { 
      logger.error("error", "Error reading har files from location!"); 
      throw err;  // propagate error 
     }).then(function(data){ 
      return fs.writeFile(writeFilePath + harFileName + ".json", data).catch(function(err) { 
       logger.error("error", "Error writing to harFile!"); 
       throw err; // propagate error 
      }); 
     }).then(function(){ 
      console.log("data written successfully: "); 
     }).catch(function(err){ 
      // either one of the errors 
     }); 

}); 

請記住,當你有一個.catch()處理程序,錯誤被認爲是「處理」,生成的承諾變得滿足,沒有拒絕。所以,如果你想捕捉特定地點的錯誤(所以你確切知道它來自哪裏),但是你希望得到的承諾仍然被拒絕,那麼你可以返回被拒絕的承諾或重新拋出同樣的錯誤。


根據您的附加問題如何返回harFiles,你需要周圍的承諾時,一切都做的是它和harFiles解決。 Bluebird的Promise.map()對此很有用,因爲它會爲你做迭代並返回一個主要承諾。以下是該代碼部分的外觀:

function someFunc() { 

    var harPath = projectJSON.project.harfile.location; 
    var harFileNames = projectJSON.project.transactions.transactionsName; 
    var harFilePath; 
    var harFiles = {}; 
    var writeFilePath = "../temp/" 

    return Promise.map(harFileNames, function(harFileName) { 
     harFilePath = harPath + "/" + harFileName + ".har"; 

     return fs.readFileAsync(harFilePath, "utf-8") 
      .then(function(data){ 
       harFiles[JSON.parse(data).log.pages[0].id] = JSON.parse(data); 
       return data; 
      }, function(err) { 
       logger.error("error", "Error reading har files from location!"); 
       throw err;  // propagate error 
      }).then(function(data){ 
       return fs.writeFile(writeFilePath + harFileName + ".json", data).catch(function(err) { 
        logger.error("error", "Error writing to harFile!"); 
        throw err; // propagate error 
       }); 
      }).then(function(){ 
       console.log("data written successfully: "); 
      }).catch(function(err){ 
       // either one of the errors 
      }); 

    }).then(function() { 
     // all results are in harFiles array here 
     return harFiles; 
    }); 
} 

someFunc().then(function(hFiles) { 
    // hFiles should be your files object 
}); 
+0

謝謝您的回答。 在你的例子中,你已經在每個catch塊中拋出錯誤,以便使得到的promise被拒絕,是嗎? 還有一個問題,這段代碼是在一個函數中。一旦它讀取所有文件並將它們寫入新位置(如示例中所寫),我想返回** harFiles **對象數組。當我在每個循環之後包含我的返回行時,由於異步行爲,它返回'undefined'。 我怎麼能這樣做? – nzhmz

+0

@Hamza - 是的,'throw err'行是爲了確保所產生的promise保持被拒絕,所以這個鏈中的進一步操作不會被嘗試,並且被拒絕的原因會一直到最後。我在關於返回'harFiles'的回答中添加了另一節。 – jfriend00

+0

非常感謝您的幫助。 – nzhmz