For example we have a function to check the filesize:
const fs = require('fs');function fileSize (fileName, cb) {
if (typeof fileName !== 'string') {
throw new TypeError('filename should be string')
} fs.stat(fileName, (err, stats) => {
if (err) {
return cb(err)
} cb(null, stats.size);
});
}fileSize(__filename, (err, size) => {
if (err) throw err; console.log(`Size in KB: ${size/}`);
});
console.log('Hello!'); /*
Hello!
Size in KB: 0.44921875
*/
It works fine, but the ‘fileSize’ function has a problem,
if (typeof fileName !== 'string') {
return new TypeError('filename should be string')
}
those part of code run in sync, not async, but the rest part of code for ‘fileSize’ is aysnc function. Normally a function should be always sync or async.
Why? If we call the fileSize with wrong params:
fileSize(, (err, size) => {
if (err) throw err; console.log(`Size in KB: ${size/}`);
});
It ouput:
/*
throw new TypeError('filename should be string')
^TypeError: filename should be string
*/
Our console.log() is not running…
To fix it we can use ‘process.nextTick’, it run before ‘event loop’ and right after ‘call stack is empty’:
const fs = require('fs');function fileSize (fileName, cb) {
if (typeof fileName !== 'string') {
return process.nextTick(
cb,
new TypeError('filename should be string')
)
} fs.stat(fileName, (err, stats) => {
if (err) {
return cb(err)
} cb(null, stats.size);
});
}fileSize(, (err, size) => {
if (err) throw err; console.log(`Size in KB: ${size/}`);
});
console.log('Hello!');
/*
Hello!
C:\Users\z000879\learn\maybe\src\process.js:21
if (err) throw err;
^TypeError: filename should be string
*/
This time, our ‘Hello’ was printed out before error was throw.