[Node.js] process.nextTick for converting sync to async

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/1024}`);
});
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(1, (err, size) => {
    if (err) throw err;

    console.log(`Size in KB: ${size/1024}`);
});

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(1, (err, size) => {
    if (err) throw err;

    console.log(`Size in KB: ${size/1024}`);
});
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.

猜你喜欢

转载自www.cnblogs.com/Answer1215/p/10617901.html