2015-10-23 2 views
4

Я написал следующий код для создания объекта с настройкой KEYS для комментариев заголовков, а VALUES - для файлов, разделяющих эти заголовки. Если нет заголовка, имя файла записывается в файл. Я хотел бы написать этот объект заголовка в файл, но он записывается до завершения объекта. Я понимаю, почему это происходит, но я не могу решить проблему. Вот код для записи объекта в файл:Записать в файл после завершения задач async

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

ответ

1

Он по-прежнему требует дальнейшего рефакторинга, но должен дать вам идею:

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

Я очень ценю, что вы нашли время, чтобы написать это для меня! –

1

Я думаю, что проблема заключается в том, что вы используете асинхронные функции (погружения) внутри синхронные (dirs.forEach) и следующая функция в вашем коде (который записывает allHeaders в файл), выполняемый ранее, тогда все директивы фактически обрабатываются.

Чтобы исправить это, вы можете использовать «асинхронной» модуля, например:

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

Спасибо за взглянуть, но это, кажется, что функция, содержащая запись в файл, никогда не запускается. Я думаю, что async.each - хорошее изменение. –

+0

Удостоверьтесь, что вы вызываете функцию next() для каждой директивы внутри async.each() –

Смежные вопросы