node.js等待任务完成

node.js Wait for task to be finished

本文关键字:任务 等待 js node      更新时间:2023-09-26

所以我正在编写这个node.js程序,将XML文件导入JSON对象数组。我有两个文件要导入,teachers.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来做这件事,但它不会等到两个文件完成后再导入。

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个文件,加载顺序对我来说无关紧要。

有线索吗?谢谢

您在async.parallel()函数中执行callback()太早了,因为到那时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);
});