node.js等待任务完成

时间:2014-09-28 18:55:36

标签: javascript node.js

所以我正在编写这个node.js程序,将XML文件导入JSON对象的数组中。我有2个要导入的文件,teacher.xml和students.xml。

教师和学生包含数千个关于教师和学生的信息。我的代码完全覆盖了那部分。

这是我用于解析文件的javascript文件:

var fs = require('fs');
var xmldom = require('xmldom');
var async = require('async');

// Parse `catalog` xml file and call `callback(catalog domxml root)`
function parse_catalog(catalog, callback) {
    // Read xml file content
    fs.readFile(catalog, function (err, data) {
        if (err) {
            throw 'Error reading XML catalog';
        } else {
            // Parse xml content and return dom root
            var domRoot = new xmldom.DOMParser().parseFromString(data.toString());
            // Call callback passing dom root
            callback(domRoot)
    }
});
}

我有两个这样的方法将xml转换为json并且它完美地工作(一个用于教师,一个用于学生)

// Convert teacher XML into json format in a array
function convert_teachers(domCatalog) {
    var teachers = domCatalog.getElementsByTagName('teacher');
    var teachers_arr= [];
    for (var i = 0; i < teachers .length; i++) {
        var teacher= teachers[i];
        ...
        //Reading the xml 

        teachers_arr.push({
        ...
        //Create the json

        });
    }
    console.log("Teachers are now in JSON format ");
}

所以最后我要做的就是:

parse_catalog('teachers.xml', convert_teachers);

当我这样做时:

parse_catalog('teachers.xml', convert_teachers);
parse_catalog('students.xml', convert_students);

根据要导入的元素数量,一个或另一个将首先完成,我认为这是正常的。

我想要的是等待两者都被导入然后进行一些javascript操作,这就是我被困住的地方。

我尝试使用异步执行此操作,但它不会等到导入完成两个文件。

async.parallel([
    function(callback) {
        parse_catalog('teachers.xml', convert_teachers);
        callback();
    },

    function(callback) {
        parse_catalog('students.xml', convert_students);
        callback();
    }
], function(err) { 
    if (err) return next(err);

    console.log("Finished");
    //Enventually some Javascript manipulations on the two arrays

});

实际上输出:

Finished
Teachers are now in JSON format
Students are now in JSON format

或取决于文件大小

Finished
Students are now in JSON format
Teachers are now in JSON format

我想要的更像是:

Teachers are now in JSON format (or students)
Students are now in JSON format (or teachers)
Finished

我打算再加载2个文件,他们加载的顺序对我来说无关紧要。

任何线索?谢谢!

1 个答案:

答案 0 :(得分:1)

您过早地在callback()功能中执行async.parallel(),因为那时fs.readFile()尚未开始。尝试这样的事情:

function parse_catalog(catalog, callback) {
  // Read xml file content
  fs.readFile(catalog, function(err, data) {
    if (err)
      return callback(err);

    // Parse xml content and return dom root
    var domRoot = new xmldom.DOMParser().parseFromString(data.toString());

    // Call callback passing dom root
    callback(null, domRoot);
  });
}

// Convert teacher XML into json format in a array
function convert_teachers(domCatalog) {
  var teachers = domCatalog.getElementsByTagName('teacher');
  var teachers_arr = [];
  for (var i = 0; i < teachers .length; i++) {
    var teacher = teachers[i];
    ...
    //Reading the xml 

    teachers_arr.push({
    ...
    //Create the json

    });
  }
  console.log('Teachers are now in JSON format');
  return teachers_arr;
}
// and similarly for `convert_students`

async.parallel({
  teachers: function(callback) {
    parse_catalog('teachers.xml', function(err, domCatalog) {
      if (err)
        return callback(err);
      var teachers = convert_teachers(domCatalog);
      callback(null, teachers);
    });
  },
  students: function(callback) {
    parse_catalog('students.xml', function(err, domCatalog) {
      if (err)
        return callback(err);
      var students = convert_students(domCatalog);
      callback(null, students);
    });
  }
}, function(err, results) { 
  if (err) return next(err);

  console.log('Finished');

  // here you have `results.teachers` and `results.students`
  console.dir(results);
});