index.js
function _explore(start, callfile, calldir, options, done) {
    const {fs, followSymlink, resolve} = options;

    let count = 0;

    function take() {
        ++count;
    }

    function give(err) {
        if (--count === 0 || err) {
            done(err);
        }
    }

    // Start process
    take();
    fs.lstat(start, (err, stats) => {
        let linkStats;
        if (err) {
            give(err);
            return;
        }

        if (stats.isSymbolicLink() && (followSymlink || resolve)) {
            linkStats = stats;
            fs.realpath(start, (err, resolvedPath) => {
                if (err) {
                    give(err);
                    return;
                }

                fs.lstat(resolvedPath, (err, stats) => {
                    if (err) {
                        // invalid symlink
                        callfile(start, stats, give);
                        return;
                    }

                    __doExplore(start, callfile, calldir, options, stats, linkStats, take, give);
                });
            });
        } else {
            __doExplore(start, callfile, calldir, options, stats, linkStats, take, give);
        }
    });
}
function _explore(start, callfile, calldir, options, done) {
    const {fs, followSymlink, resolve} = options;

    let count = 0;

    function take() {
        ++count;
    }

    function give(err) {
        if (--count === 0 || err) {
            done(err);
        }
    }

    // Start process
    take();
    fs.lstat(start, (err, stats) => {
        let linkStats;
        if (err) {
            give(err);
            return;
        }

        if (stats.isSymbolicLink() && (followSymlink || resolve)) {
            linkStats = stats;
            fs.realpath(start, (err, resolvedPath) => {
                if (err) {
                    give(err);
                    return;
                }

                fs.lstat(resolvedPath, (err, stats) => {
                    if (err) {
                        // invalid symlink
                        callfile(start, stats, give);
                        return;
                    }

                    __doExplore(start, callfile, calldir, options, stats, linkStats, take, give);
                });
            });
        } else {
            __doExplore(start, callfile, calldir, options, stats, linkStats, take, give);
        }
    });
}
function _explore ( start , callfile , calldir , options , done ) { const { fs , followSymlink , resolve } = options ; let count = 0 ; function take ( ) { ++ count ; } function give ( err ) { if ( -- count === 0 || err ) { done ( err ) ; } } // Start process take ( ) ; fs . lstat ( start , ( err , stats ) => { let linkStats ; if ( err ) { give ( err ) ; return ; } if ( stats . isSymbolicLink ( ) && ( followSymlink || resolve ) ) { linkStats = stats ; fs . realpath ( start , ( err , resolvedPath ) => { if ( err ) { give ( err ) ; return ; } fs . lstat ( resolvedPath , ( err , stats ) => { if ( err ) { // invalid symlink callfile ( start , stats , give ) ; return ; } __doExplore ( start , callfile , calldir , options , stats , linkStats , take , give ) ; } ) ; } ) ; } else { __doExplore ( start , callfile , calldir , options , stats , linkStats , take , give ) ; } } ) ; }
Explore a file or a directory with no checking of paramters correctness

Calling next with err cancels the reading
Not calling next will make the process hang forever
If you want fast reading, call next before processing the file or folder
If you want listing control, call next after you processed the file or folder
@param  {String}     start    File or folder to read
@param  {Function}   callfile called every time a file is encountered with (path, stats, next)
@param  {Function}   calldir  called every time a folder is encountered with (path, stats, files, 'begin|end', next)To skip folder, call next(null, true) on begin
@param  {Object}     options  options.resolve[=true] => resolve symlink; options.followSymlink => explore symlink if directory
@param  {Function}   done     called when there are no more file nor folders to read
Explore a file or a directory with no checking of paramters correctness