简体   繁体   中英

Using Bluebird Promises in Node.JS

In my application, I am trying to read a file and then write the contents of the file to another file.

I have used bluebird promises to do this. I need help to confirm that my understanding on using promises is right in my implementation.

The questions that I have is,

  1. In my example, I am first reading the file, then once the file read the file, I am writing the contents into another file in my next '.then' block. Once the contents are written into a file I need log a message. I have included that in the second '.then' block. I need to know whether my understanding is correct on promises. will the second '.then' block works as the callback function for writefile statement?

  2. I need to write more meaningful log messages. Different error messages if an error occurs while reading the file and writing the file. How can I do this with catch blocks?

Thanks in advance!

The code example is below.

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!");

        });

});

If you want to capture each error separately, then you can put an error handler immediately after each operation so you can directly capture that particular error.

Then, to propagate the error, you can rethrow the error value.

Then, you want to switch to fs.writeFileAsync() so everything is async and is using promises.

Then, you need to return the promise from 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
        });

});

Keep in mind that when you have a .catch() handler, the error is considered "handled" and the resulting promise becomes fulfilled, not rejected. So, if you want to capture the error in a particular spot (so you know exactly where it came from), but you want the resulting promise to remain rejected, then you can either return a rejected promise or rethrow the same error.


Per your additional question about how to return harFiles , you will need a surrounding promise that gets resolved with harFiles when everything is done. Bluebird's Promise.map() is useful for that as it will both do the iteration for you and return a master promise. Here's how that part of the code could look:

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
});

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM