Writing to a file after completion of asynchronous tasks

I wrote the following code to create an object with KEYS settings for header comments, and VALUES for files that share these headers. If there is no header, the file name is written to the file. I would like to write this header object to a file, but it is written before the completion of the object. I understand why this is happening, but I cannot solve the problem. Here is the code to write the object to a file:

stringObj = JSON.stringify(allHeaders, null, 4);
    fs.writeFile(currentHeads, stringObj, function(err) {
        if (err) {
            console.log(err);
        }
    });
    console.log('Complete!');

And here is the rest of the script:

    "use strict";

var fs = require('fs'),
    dive = require('dive'),
    subdirs = require('subdirs'),
    cpFile = __dirname + "/" + "header.txt",
    noCopy = __dirname + "/" + "noCopyright.txt",
    currentHeads = __dirname + "/" + "currentHeaders.txt",
    re = /(\/\*(?:(?!\*\/).|[\n\r])*\*\/)/, // matches first multi-line comment
    walkDir,
    allHeaders = {},
    stringObj,
    top;


fs.readFile(cpFile, 'utf8', function(err, copyRight) {
    subdirs(__dirname, 1, function(err, dirs) {
        if (err) {
            return console.log(err);
        }
        dirs.forEach(function(dir) {
            if (dir.match(/.*\/src$/)) {
                dive(dir, { all: false }, function(err, file) {
                    if (err) {
                        return console.log(err);
                    }
                    fs.readFile(file, 'utf8', function(err, data) {
                        if (err) {
                            return console.log(err);
                        }
                        if (data.match(re)) {
                            top = data.match(re);
                            if (allHeaders[top[0]]) {
                                allHeaders[top[0]].push(file);
                            } else {
                                allHeaders[top[0]] = [file];
                            }
                        } else {
                            fs.appendFile(noCopy, file + "\n", function(err) {
                                if (err) {
                                    return console.log(err);
                                }
                            });
                        }
                    });
                });
            }
        });
    });
});
+4
source share
2 answers

It still requires further refactoring, but should give you an idea:

function processDir(dir, callback) {
   dive(dir, {all: false}, function (err, file) {
      if (err) {
        return callback(err);
      }

      fs.readFile(file, 'utf8', callback);
   });
}

fs.readFile(cpFile, 'utf8', function(err, copyRight) {
  if (err) return console.error(err);

  subdirs(__dirname, 1, function (err, dirs) {
    if (err) return console.error(err);

    async.each(dirs, function (dir, next) {
      if (!dir.match(/.*\/src$/)) return next();

      processDir(dir, function(err, data) {
        if (err) return next(err);

        if (!data.match(re)) {
          return fs.appendFile(noCopy, file + "\n", next);
        }

        top = data.match(re);
        if (allHeaders[top[0]]) {
          allHeaders[top[0]].push(file);
        } else {
          allHeaders[top[0]] = [file];
        }
        return next();
      });
    }, function (err) {
      if (err) return console.error(err);

      stringObj = JSON.stringify(allHeaders, null, 4);
      fs.writeFile(currentHeads, stringObj, function(err) {
        if (err) return console.error(err);

        console.log('Complete!');
      });
    });
  });
});
+1
source

, , () (dirs.forEach) ( allHeaders ), , .

, "async", :

async.each(dirs, function(dir, next) {
  // process dir here, in case of error call return next(err), otherwise call return next();
}, function(err) {
   // process err somehow
   // if there is no error, all directives are processed, write allHeaders to file

   stringObj = JSON.stringify(allHeaders, null, 4);
   fs.writeFile(currentHeads, stringObj, function(err) {
     if (err) {
        console.log(err);
     }

     console.log('Complete!');
   });
});
+1

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


All Articles