JS builds an object recursively

I am trying to create a file structure index using nodeJS. I use the fs.readir function to iterate over files, which works fine. My problem comes down to the directory structure and returns a complete object with the correct structure.

I have a simple function called ident that, when the given file name "myfile.txt" returns an object {name: "myfile", enter: "txt"}, which will explain this part of the function below ..

My problem is that nothing is returned when I run the pointer into the variable "me". However, the string console.log (results) returns. This leaves me confused.

Any help would be greatly appreciated!

indexer = 
    function(directory){     
        Self.indexleft++;
        var results = {};
        Self.client.readdir(directory, function(err,fileLst){
            if(err){ return; }
            for(var count=0; count < fileLst.length; count++){
                var ident = identify(fileLst[count]);
                if(ident.type = 'dir'){
                    var descendant = (directory !== '') ? 
                        directory + '\\' + ident.name : ident.name;
                    ident.children = indexer(descendant);
                                }
                    //directory = (directory.split('\\').pop());
                    results[ident.name] = ident;
                 }
                 console.log(results);
                 return results;
             });
         }
         var me = indexer(''); console.log(me);

:: - , , . . - , !

() :

var events = require('events'),
    event = new events.EventEmitter(),
setToValue = function(obj, value, path) {
    path = path.split('\\');
    for (i = 0; i < path.length - 1; i++)
        obj = obj[path[i]];
    obj[path[i]] = value;
},
identify = function(file){
    var split = file.split('.'),
        type = (split.length > 1) ? split.pop() : 'dir',
        filename = split.join('.');
    return { name: filename, type: type };
};
Indexer = function(cli,dir,callback){  
    this.client = cli; // File reading client
    this.startDir = dir; // Starting directory
    this.results = {}; // Result object
    this.running = 0; // How many itterations of start() are running
    this.start(dir); // Start indexing
    this.monit(); // Start never returns anything, monit() checks ever 5 seconds and will fire callback if 0 itterations are running.
    this.callbackDone = false; // Checks whether the callback has already been fired. Important in case of interval staggering
    this.cb = callback;
}
Indexer.prototype = {
    start: function(directory){        
        var Self = this;
        Self.running++;
        Self.client.readdir(directory, function(err,fileLst){
            if(err){ Self.running--; return; }
            for(var count=0; count < fileLst.length; count++){
                var ident = identify(fileLst[count]);
                var descendant = (directory !== '') ? directory + '\\' + ident.name : ident.name;
                if(ident.type === 'dir'){                
                    Self.start(descendant);
                }
                setToValue(Self.results, ident, descendant);
            }
            Self.running--;
            console.log('running' + Self.running);
        });
    },
    monit: function(){
        var Self = this;
        Self.intervalA = setInterval(function(){
            if(Self.running < 1){                
                if(!Self.callbackDone){ 
                    this.callbackDone=true; 
                    Self.cb(Self.results);
                }
                clearInterval(Self.intervalA);

            }
        }, 5000)
    }
}

var ix = new Indexer(Self.client,'',function(res){
                        console.log("Index Complete!");
                        fs.writeFile(path.join(Self.localLibBase,'/index.json'), JSON.stringify(res), (err)=> {
                            console.log("FileWrite Complete!");
                        });
                    });

:

{
    "Applications" : {
        "name" : "Applications",
        "type" : "dir",
        "Microsoft Exchange Server 2007" : {
            "name" : "Microsoft Exchange Server 2007",
            "type" : "dir",
            "Microsoft Exchange Server 2007 SP1" : {
                "name" : "Microsoft Exchange Server 2007 SP1",
                "type" : "iso"
            }
        }
    }
}
0
2

, . .

. promises.

, promises.

. , "dir": .

:

var indexer = function(directory) {
    // return a promise object
    return new Promise(function (resolve, reject) {
        Self.indexleft++;
        var results = {};
        Self.client.readdir(directory, function(err,fileLst){
            if(err) { 
                reject(); // promise is rejected
                return;
            }
            // "Iterate" over file list asyonchronously
            (function nextFile(fileList) {
                if (!fileList.length) {
                    resolve(results);  // promise is resolved
                    return;
                }
                var file = fileLst.shift(); // shop off first file
                var ident = identify(file); 
                results[ident.name] = ident;
                if(ident.type === 'dir'){ // There was a bug here: equal sign!
                    var descendant = directory !== '' 
                            ? directory + '\\' + ident.name : ident.name;
                    // recursively call indexer: it is again a promise!        
                    indexer(descendant).then(function (result) {
                        ident.children = result;
                        // recursively continue with next file from list
                        nextFile(fileList);
                    });
                } else {
                    nextFile(fileLst);
                }
            })(fileLst); // start first iteration with full list
        });
    });
};

// Call as a promise. Result is passed async to callback. 
indexer('').then(function(me) {
    console.log(me);
});

, :

// Below code added to mimic the external references -- can be ignored
var filesystem = [
    "",
    "images",
    "images\\photo.png",
    "images\\backup",
    "images\\backup\\old_photo.png",
    "images\\backup\\removed_pic.jpg",
    "images\\panorama.jpg",
    "docs",
    "docs\\essay.doc",
    "readme.txt",
];

var Self = {
    indexLeft: 0,
    client: {
        readdir: function (directory, callback) {
            var list = filesystem.filter( path => 
                    path.indexOf(directory) == 0 
                    && path.split('\\').length == directory.split('\\').length + (directory!=='')
                    && path !== directory
            ).map ( path => path.split('\\').pop() );
            setTimeout(callback.bind(null, 0, list), 100);
        }
    }
}

function identify(item) {
    return {
        name: item,
        type: item.indexOf('.') > -1 ? 'file' : 'dir'
    };
}
// Above code added to mimic the external references -- can be ignored

var indexer = function(directory) {
    // return a promise object
    return new Promise(function (resolve, reject) {
        Self.indexleft++;
        var results = {};
        Self.client.readdir(directory, function(err,fileLst){
            if(err) { 
                reject(); // promise is rejected
                return;
            }
            // "Iterate" over file list asyonchronously
            (function nextFile(fileList) {
                if (!fileList.length) {
                    resolve(results);  // promise is resolved
                    return;
                }
                var file = fileLst.shift(); // shop off first file
                var ident = identify(file); 
                results[ident.name] = ident;
                if(ident.type === 'dir'){ // There was a bug here: equal sign!
                    var descendant = directory !== '' 
                            ? directory + '\\' + ident.name : ident.name;
                    // recursively call indexer: it is again a promise!        
                    indexer(descendant).then(function (result) {
                        ident.children = result;
                        // recursively continue with next file from list
                        nextFile(fileList);
                    });
                } else {
                    nextFile(fileLst);
                }
            })(fileLst); // start first iteration with full list
        });
    });
};

// Call as a promise. Result is passed async to callback. 
indexer('').then(function(me) {
    console.log(me);
});
Hide result
+2

, , , .

, , . , , .

, , name

{ "Applications" : {
    "name" : "Applications",
    "type" : "dir",
    "name" : {
      "name" : "name"
       ... } } }

, . , .

const co = require('co')
const {stat,readdir} = require('fs')
const {extname,join} = require('path')

// "promisified" fs functions
const readdirp = path =>
  new Promise ((t,f) => readdir (path, (err, res) => err ? f (err) : t (res)))

const statp = fd =>
  new Promise ((t,f) => stat (fd, (err,stats) => err ? f (err) : t (stats)))

// tree data constructors
const Dir = (path, children) =>
  ({type: 'd', path, children})

const File = (path, ext) =>
  ({type: 'f', path, ext})

// your function
const indexer = function* (path) {
  const stats = yield statp (path)
  if (stats.isDirectory ())
    return Dir (path, yield (yield readdirp (path)) .map (p => indexer (join (path,p))))
  else
    return File (path, extname (path))
}

, Self.client. - , , .

Ok ,

$ mkdir test
$ cd test
$ mkdir foo
$ touch foo/disk.iso foo/image.jpg foo/readme.txt
$ mkdir foo/bar
$ touch foo/bar/build foo/bar/code.js foo/bar/migrate.sql

indexer

// co returns a Promise
// once indexer is done, you will have a fully built tree
co (indexer ('./test')) .then (
  tree => console.log (JSON.stringify (tree, null, '  ')),
  err  => console.error (err.message)
)

( \n )

{
  "type": "d",
  "path": "./foo",
  "children": [
    {
      "type": "d",
      "path": "foo/bar",
      "children": [
        { "type": "f", "path": "foo/bar/build", "ext": "" },
        { "type": "f", "path": "foo/bar/code.js", "ext": ".js" },
        { "type": "f", "path": "foo/bar/migrate.sql", "ext": ".sql" }
      ]
    },
    { "type": "f", "path": "foo/disk.iso", "ext": ".iso" },
    { "type": "f", "path": "foo/image.jpg", "ext": ".jpg" },
    { "type": "f", "path": "foo/readme.txt", "ext": ".txt" }
  ]
}

indexer ,

co (indexer ('./test/foo/disk.iso')) .then (
  tree => console.log (JSON.stringify (tree, null, '  ')),
  err  => console.error (err.message)
)

{ "type": "f", "path": "./foo/disk.iso", "ext": ".iso" }
0

Source: https://habr.com/ru/post/1652633/


All Articles