I have been trying to learn node.js, but one thing I couldn't understand was the order of execution of this code:
var zlib = require("zlib");
var input = '.............text...............';
zlib.deflate(input, function(err, buffer) {
if (!err) {
console.log("deflate (%s): ", buffer.length, buffer.toString('base64'));
zlib.inflate(buffer, function(err, buffer) {
if (!err) {
console.log("inflate (%s): ", buffer.length, buffer.toString());
}
});
zlib.unzip(buffer, function(err, buffer) {
if (!err) {
console.log("unzip deflate (%s): ", buffer.length, buffer.toString());
}
});
}
});
zlib.deflateRaw(input, function(err, buffer) {
if (!err) {
console.log("deflateRaw (%s): ", buffer.length, buffer.toString('base64'));
zlib.inflateRaw(buffer, function(err, buffer) {
if (!err) {
console.log("inflateRaw (%s): ", buffer.length, buffer.toString());
}
});
}
});
Output:
deflate (18): eJzT00MCJakVJXqoAABxWgbO
deflateRaw (12): 09NDAiWpFSV6qAAA
inflate (32): .............text...............
unzip deflate (32): .............text...............
inflateRaw (32): .............text...............
How come "deflateRaw" is output before "inflate"? I know node.js could runs asynchronously, but could anyone explain why this piece of code is asynchronous, and how the order of execution is determined?
Well, it is asynchronous :)
As soon as you pass a callback function to a piece of the async code you don't know which order will it be executed.
You can think of your code order following way:
Flow1:
start deflate with cb1;
start deflateRaw with cb2;
done, the order of starting was guaranteed but not the oder of callbacks execution
Flow2: either cb1 or cb2 starts to get executed
etc...
I know node.js could runs asynchronously, but could anyone explain why this piece of code is asynchronous?
Why the zliblibrary is asynchronous, I cannot say for sure. It may use intermediate files for I/O, and we know that I/O is (generally, preferably) asynchronous in node.js. It could also use a worker process behind the scenes or some other asynchronous mechanism.
Asynchronous code requires either callbacks, promises, streams, or some other type of control flow pattern.
However, you could use a callback with synchronous code, so you're right to ask how you would know.
I think the best advice is to assume it's asynchronous if it takes a callback. To handle such a case, the code you want to run after asynchronous function A should just go into the callback, whether it is synchronous or asynchronous. That way, you know it will work. The API developer designed it that way for a reason, so don't try to fight their design by exploiting something that may be synchronous. Just go with the flow :)
The reasons this is safe are: