Search code examples
node.jsasync-awaitv8node-deasync

Async vs Deasync in reality


The background

I'm writing my next server project in node. The previous version was written in language D, which is majorly an synchronized implementation. We all know, that JS uses a lot of async This is good for performance, but hard to maintain (at least for me). Because node and its node modules might use different async approach (callback, promise and await/async), which makes the code looks not in a consistent style. I'm looking for a balanced approach, that not only can create a high quality and performance node application, but fit the common programming style.

The problem

After first round prototyping, I have my first server. When I start the server, it will first read configuration and then load a set of modules. I expect them to be loaded sequentially. But as I mentioned above, node modules might work in async way. I expect module b to be loaded exactly when module a is loaded, I must use Promise pattern. I have to write code in crazy way, although Promise is already a very programmer friendly approach.

No, I go to the other direction. Currently I choose deasync, which is a gyp module for node. It can really blocks the code execution like this.

const deasync = require('deasync');

let done = false;
loadModule1Async((err, result) => {
    done = true;
});
deasync.loopWhile(() => !done);

done = false;
loadModule2Async((err, result) => {
    done = true;
});
deasync.loopWhile(() => !done);

OR even more magical like this

const deasync = require('deasync');

const loadModule1Sync = deasync(loadModule1Async);
const loadModule2Sync = deasync(loadModule2Async);

try {
    loadModule1Sync();
    loadModule2Sync();
} catch(ex) {
    console.error(ex);
}

IMO, the deasync way is more straightforward to me, but I have two concerns:

  1. It need to be compiled against the target platform, so that the deployment process will be complicated for production.
  2. I checked its issue list. There are some known serious issue, e.g. hanging in some extream cases.

The question

Can the coming new feature async/await really do the same thing as deasync does? If it is never gonna happen due to the JS nature. I might stop thinking about this.

Please share me some lights on the way to node.


Solution

  • I don't know too much about how deasync works, I took a look at it and looks very convenient, but I don't think it's thought to be used through all your code in a server.

    little bit performance downgrade

    It depends on your case, but it could be more than a little downgrade. You are wrapping all your asynchronous methods in your code, that does not sound good in general. Doing a benchmark could be a good idea.

    Other thing:

    Because node and its node modules might use different async approach (callback, promise and await/async)

    In general modules follow callback style, Promise style, or both of them. Most of the big ones are compatibles with both of them (in general if you don't pass a callback a Promise is returned).

    async/await is different, this works on top of Promises, so a module method that returns a Promise can be used with async/await in your code.

    So answering your question, I would stick with Promises in the whole code, it's the tendency now, and in general they are easier to deal with, compared to callbacks.

    To me async/await is the easiest way, since it keeps calls asynchronous, but the code is written in a synchronous way. Sadly at the moment async/await is only usable in Node.js through a flag, so it's not recommended to be used in production.