3

I want to create functions that fetches data from database for example executeQuery(sql). But I don't want any promise returned from this function or want to pass any callback function. I just want to return the result of the query.

For example:

var rows = executeQuery('SELECT * FROM table');
console.log('database query completed:', rows);

I know this is not how javascript works. I've also gone through number of stackoverflow questions that also wanted this thing. But everyone says that there's no way to do that.

Now here's my question if that's not possible then how functions like fs.readFileSync() work. These functions neither require any callbacks nor they return any promise. They just do what they are defined to do.

Amarjit Singh
  • 2,068
  • 19
  • 52
  • You could build your own `mysql` package using https://www.npmjs.com/package/sync-socket – Paul Jan 20 '19 at 00:07

4 Answers4

1

Update: Like @Paulpro said in the comments, This answer below would never work, because the code will be stuck in infinite loop. so you better go with a Promises


I advise like @happy-machine & @bergur, it's better to use Promises. but if you wanna know how fs.readFileSync() works, then go read fs module code in nodejs source code.

You'll find that it does a do {} while() and you can do the same thing to sync your async code like this

var rows;
executeQuery('SELECT * FROM table').then(
  promiseResponse => {
   rows = promiseResponse
  }
)
do {
  // nothing
} while(!rows) // rows is undefined
console.log('database query completed:', rows);
Oudmane
  • 97
  • 1
  • 5
  • 2
    This has an infinite loop that doesn't modify `rows`, it can never reach the console.log line. – Paul Jan 19 '19 at 23:59
  • I edited the answer, the function to an arrow function, which will change rows – Oudmane Jan 20 '19 at 00:04
  • The arrow function never runs because there is an infinite loop running. – Paul Jan 20 '19 at 00:07
  • 2
    Just try `var rows; setTimeout( _ => { rows = true; }, 100 ); do {} while (! rows); console.log('never reached');` to see what I mean. – Paul Jan 20 '19 at 00:09
0

fs.readFileSync() can be synchronous because it is just working with your local file system, which might be a quick operation. If your database is local it also could conceivably be written to be synchronous also. However if your database is on the net executeQuery will have to send an http request and wait for a response which can take a long time and might not be possible to do synchronously due to such as the following:

Note: Starting with Gecko 30.0 (Firefox 30.0 / Thunderbird 30.0 / SeaMonkey 2.27), synchronous requests on the main thread have been deprecated due to the negative effects to the user experience.

Steve
  • 366
  • 2
  • 14
-1

You could use async/wait. That would give you pretty much the same syntax as readFileSync - that is no promise chains or callbacks.

var rows = await executeQuery('SELECT * FROM table')
console.log('database query completed:', rows) // this now works

You would just have to wrap it inside async function.

Just to avoid confusion. The function is still asynchronous, its just syntax sugar that makes it easier to read the code.

Bergur
  • 3,962
  • 12
  • 20
  • The await keyword can only be used inside functions that are declared as async. That's why I want to know how `fs.readFileSync()` works. – Amarjit Singh Jan 19 '19 at 22:26
  • It works by blocking the event loop in JavasScript: Check out: https://nodejs.org/en/docs/guides/event-loop-timers-and-nexttick/ and https://www.youtube.com/watch?v=8aGhZQkoFbQ Just note that the design philosphy in nodeJS is to have it non-blocking. So you would be going agains that design pattern. – Bergur Jan 20 '19 at 00:06
  • Yes, "use await" is what everyone says. The horrible side effect is that it causes "async propagation hell". If that async is 4 levels down in the call chain, then every parent function all the way up has to become an async function too, and an await has to be applied at every call going down. JS really needs an way to do a sync call on code and hide the promise mechanism because there are times you must do A() before B() and there is nothing else to do and you don't want to start adding async/await words everywhere. I'm in Node doing backend work not a browser, waiting an extra 200ms is fine. – kbrannen Jun 14 '23 at 17:31
-2

Sync is synchronous and blocks execution until finished. The Sync methods of fs return their results as return values.

The other fs non sync methods are asynchronous and return immediately while they function in the background. You pass a callback function which get called when they finish.

Promises are a bit of a nightmare when you start using Javascript, but because Javascript only has one thread they are part of the beauty of Javascript once you get used to them. If you use Sync functions you block the thread which is generally not a good idea, especially if you're not using workers.

I wrote a post about wrapping you head around promises if you'd like to check it out here

Why Does Async Always Return a Promise?

Happy Machine
  • 987
  • 8
  • 30
  • Sorry. But that's not what I am asking. I know how to use promises and callbacks. But I don't wanna use them – Amarjit Singh Jan 19 '19 at 22:31
  • But you can't really avoid them.. the whole point of javascript is that it's asynchronous. You cant block the thread while going off to get data from a db. And you're thumbing me down for trying to help you see that! If you wrote the code the web was built on synchronously the web literally wouldnt work. – Happy Machine Jan 19 '19 at 22:44
  • If you insist on blocking the thread there are synchronous mysql libraries https://github.com/Will-I4M/node-mysql-libmysqlclient you will not be able to make syncronous calls for the majority of libraries that provide blocking methods.. it's bad practice – Happy Machine Jan 19 '19 at 23:33