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;
}
})
}
No.
No. That's why promises don't help here. You need to use the natively asynchronous counterpart, i.e.
fs.readFile
instead offs.readFileSync
in your case.Regarding your alternatives, you probably should do neither. But if you absolutely need a synchronous function that returns a fulfilled or rejected promise (instead of throwing exceptions), you can do
or
I would disagree slightly with the others who say you should never promisify your function. There ARE cases when you want to promisify a function. For example a legacy code base that uses native processes and similar, where no callbacks and no promises were used, but you can assume the function is async and will execute within certain time.
Instead of writing a ton of setTimeout() callbacks you want to use promises.
This is how I do it for the testing purposes. Check the Ph library, especially the promisify function, and check how it is used to set up the mocha test in before function.
To make it work in IE, I use Promise CDN:
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: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).TL;DR NO, pure synchronous functions are not promisifiable in order to avoid blockage
No. For a method to be promisifiable it needs to be already asynchronous, i.e. return immediately, and also use callbacks upon finish.
For example:
Is not promisifiable because it does not return immediately and does not use callbacks. But
Is promisifiable as
BUT all those approaches are going to block on the loop anyway. The original version blocks immediately and the one using
process.nextTick()
will block on the next processor tick. Making the application unresponsive for the duration of the loop.If you wanted to make
loop1000()
asynchronous friendly you could rewrite it as:So instead of a longer blocking time it would have several smaller blockings. Then the promisified version
loop1000promisified()
could make some sense.disclaimer: code typed directly on SO w/o any test.