Search code examples
node.jsasynchronouspromisees6-promise

Promisify a synchronous method


Can I make a synchronous method into asynchronous by using promise?

For example reading a file synchronously (yes there is fs.readFile which has callback):

// Synchronous read
var data = fs.readFileSync('input.txt'); 

Should I do this:

function readFileAsync(){
    return new Promise((resolve, reject) => {
        try {
          resolve(fs.readFileSync('input.txt')); 
        } catch(err) {
          reject(err);
        }
    })
}

or use async/await:

 function async readFileAsync(){
            try {
              let result = await fs.readFileSync('input.txt'); 
              return result;
            } catch(err) {
              return err;
            }
        })
    }

Solution

  • I would re-phrase the the other to answers from "No" to "Not Really".

    First a point of clarification: In NodeJS, everything is asynchronous, except your code. Specifically, one bit of your code will never run in parallel with another bit of your code -- but the NodeJS runtime may manage other tasks (namely IO) at the same time your code is being executed.

    The beauty of functions like fs.readFile is that the IO happens in parallel with your code. For example:

    fs.readFile("some/file",
                function(err,data){console.log("done reading file (or failed)")});
    do.some("work");
    

    The second line of code will be executed while NodeJS is busily reading the file into memory. The problem with fs.readFileSync is that when you call it, NodeJS stops evaluating your code (all if it!) until the IO is done (i.e. the file has been read into memory, in this case). So if you mean to ask "can you take a blocking (presumably IO) function and make it non-blocking using promises?", the answer is definitely "no".

    Can you use promises to control the order in which a blocking function is called? Of course. Promises are just a fancy way of declaring the order in which call backs are called -- but everything you can do with a promise, you can do with setImmediate() (albeit with a lot less clarity and a lot more effort).