Reputation: 51
I just wanted to know if a 'sync'-function, run in a promise, is synchronous (and slows down other stuff) or async, like I think?
Example:
function getFileContent(filepath){
return new Promise((resolve, reject) => {
fs.readFileSync("asd.txt"));
});
}
Upvotes: 4
Views: 1345
Reputation: 55782
Ok, I get the point that it was just an example
The thing about Promise constructors is that they execute their executor
immediately.
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise
A function that is passed with the arguments resolve and reject. The executor function is executed immediately by the Promise implementation, passing resolve and reject functions (the executor is called before the Promise constructor even returns the created object).
Which means, in your example fs.readFileSync
is executed immediately and (edited) blocks the rest of your code from running (see comment)
Upvotes: 0
Reputation: 56547
Functions are synchronous. Period.
What can be asynchronous is an (abstract) process/workflow.
When someone says a function is "async" what they actually mean is that the result will be available some time later. The result is wrapped in a Promise, which is a handle to await. But the process may still be synchronous. Have a look at this example:
function foo() {
return new Promise((res, rej) => {
console.log(1);
console.log(2);
res();
});
};
function test() {
foo();
console.log(3);
};
and the output is always the same:
> test();
1
2
3
which means that each function was called one after another in a synchronous manner. And indeed if you update foo
function to:
function foo() {
return new Promise((res, rej) => {
while (true) {}
res();
});
};
you will notice that console.log(3)
never runs. And so our foo
blocks forever!
Now have a look at this example:
function test() {
Promise.resolve().then(function() {
console.log(1);
console.log(2);
});
console.log(3);
};
and note the different result: 3 1 2
. All those functions are synchronous, so why the order is different? Because .then()
postpones the execution to some later time.
All in all: sync/async is not really a property of a function, but rather a property of a workflow. And in your case it is synchronous.
Side note: this gets more complicated when exceptions are involved. Let's modify the foo
function from the first example:
function foo() {
return new Promise((res, rej) => {
throw 'myException';
});
};
function test() {
foo();
console.log(3);
};
and call test()
. Oh, wow, now 3
is first (someone may think that it should not be executed at all!!!) and the uncaught exception myException
second. Why? Because JavaScript engine postpones exception handling. Don't ask me why, I have no idea, but I'm sure there is a reason for this... like for everything. ;)
Conclusion: Promises don't make things automatically asynchronous and always await
or use .then()
with a function that returns a Promise (unless you're a ninja).
Upvotes: 5
Reputation: 239462
There are two interpretations of "async" here, and the answer to both is "no", promises don't make fs.readFileSync
any kind of asynchronous.
The first interpretation would be, does new Promise
behave like setTimeout
. It doesn't.
Promises invoke their callback functions immediately. They do not defer execution, meaning a blocking function wrapped in a promise will still block the main thread of execution.
There is no difference between these implementations:
function getFileContent(filepath){
return new Promise((resolve, reject) => {
fs.readFileSync("asd.txt"));
});
}
and
function getFileContent(filepath){
fs.readFileSync("asd.txt"));
}
Both of these call fs.readFileSync
immediately on the current callstack.
To make the function "async" (as in, to defer its execution) you need to use setTimeout
. You can wrap that in a promise, but you're adding no functional change by doing so, only syntactic sugar.
The second interpretation of "async" could be whether you can prevent your program from blocking on a call to fs.readFileSync
. That is impossible, fs.readFileSync
will always be blocking, and if it takes 10 seconds to read that file, your program will always be unresponsive for 10 seconds, no matter how you try to defer the execution with promises or setTimeout
.
The only fix is to use fs.readFile
, not fs.readFileSync
. This is why the non-sync versions of these functions exist: It is impossible to make fs.readFileSync
not break your program on large/slow reads.
Upvotes: 0