异步任务完成后写入文件

4
我编写了以下代码,用于创建一个对象,其中KEYS设置为注释头,VALUES设置为共享这些头的文件。如果没有标题,则文件名将被写入文件。我想将此标题对象写入文件,但它在对象完成之前被写入。我知道为什么会发生这种情况,但我似乎无法解决问题。以下是将对象写入文件的代码:
stringObj = JSON.stringify(allHeaders, null, 4);
    fs.writeFile(currentHeads, stringObj, function(err) {
        if (err) {
            console.log(err);
        }
    });
    console.log('Complete!');

以下是脚本的剩余部分:
    "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);
                                }
                            });
                        }
                    });
                });
            }
        });
    });
});
2个回答

1
我认为问题在于您在同步函数(dirs.forEach)中使用了异步函数(dive),而您代码中的下一个函数(将所有标题写入文件)会在所有指令实际处理之前被执行。
要解决这个问题,您可以使用“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!');
   });
});

谢谢您的查看,但似乎包含写入文件的函数从未运行。我认为async.each是一个不错的改变。 - user4479529
确保在async.each()中为每个指令调用next()函数。 - Lisa Gagarina

0

它仍需要进一步重构,但应该能给你一个想法:

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!');
      });
    });
  });
});

非常感谢您抽出时间为我解释清楚! - user4479529

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接