Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is this the correct way to wrap readFileSync in a Promise

Tags:

javascript

The reason for the below code is to get rid of callback hell/pyramid of doom. I don't fully understand i/o blocking though yet.

'use strict';

var fs = require('fs');
var co = require('co');

co(function* () {

    var fileName = 'readme.txt';

    var str =
        yield new Promise(function (resolve, reject) {
            var result;
            try {
                result = fs.readFileSync(fileName, 'utf8');
            } catch (err) {
                reject(err);
            }
            resolve(result);
        });
    console.log('result readFileSync: ' + str);

});

All I'm expecting is a yes or no answer to be honest. Hope fully if no could someone give some details as I'm trying to learn properly about JavaScript sync/async and how to harness the power of Promises.

like image 387
basickarl Avatar asked Jan 24 '16 19:01

basickarl


People also ask

Does readFileSync throw error?

log(data); }); Using the synchronous way with readFileSync . If there is a problem, an error will be thrown and you won't get to the last line.

What is the difference between ReadFile and readFileSync?

In fs. readFile() method, we can read a file in a non-blocking asynchronous way, but in fs. readFileSync() method, we can read files in a synchronous way, i.e. we are telling node. js to block other parallel process and do the current file reading process.

Is Promise all sequential or parallel?

Often Promise. all() is thought of as running in parallel, but this isn't the case. Parallel means that you do many things at the same time on multiple threads. However, Javascript is single threaded with one call stack and one memory heap.

Does FS ReadFile return Promise?

Return Value: It returns a Promise. The Promise is resolved with the contents of the file. If no encoding is specified (using options. encoding), the data is returned as a Buffer object.


2 Answers

Short answer

No

Useful answer

If you want to wrap a file read operation, try to use the async versions of Node functions as much as possible. Using readFileSync with a promise gives you no advantage over using readFileSync on its own, because readFileSync blocks the process until it is done reading, which readFile does not.

A better solution would therefore be something like this:

'use strict';

var fs = require('fs');

var readFilePromise = function(file) {
  return new Promise(function(ok, notOk) {
    fs.readFile(file, function(err, data) {
        if (err) {
          notOk(err)
        } else {
          ok(data)
        }
    })
  })
}

readFilePromise('/etc/passwd').then(function(data) {
  // do something with the data...
})
like image 154
conradkleinespel Avatar answered Oct 13 '22 12:10

conradkleinespel


The correct way is to use the Node's native util library and promisfy fs.readFile:

const path = require('path');
const fs = require('fs');

const INDEX = path.join(__dirname, 'app', 'index.html');
const readFile = require('util').promisify(fs.readFile);

readFile(INDEX)
  .then(e => console.log(e.toString()))
  .catch(e => console.log('FOOBAR ' + e));

result:

one@dolphin:~/github/resume $ node toolchain/inject.js 
FOOBAR Error: ENOENT: no such file or directory, open '/home/one/github/resume/toolchain/app/index.html'
like image 44
dman Avatar answered Oct 13 '22 12:10

dman