我对node.js相当新,我有一个起点app.js
,它调用一个名为xmlParser.js
的文件,它使用xml2js
节点模块解析输入的xml文件。这就是app.js
的样子,
//include the modules
var express = require('express'),
app = express(),
ejs = require('ejs'),
xmlParser = require('./utils/xmlParser.js');
//save the pain of writing .ejs after each render
app.set("view engine","ejs");
//these will hold the result of the function in the file xmlParser
var listJSON, logJSON = {};
app.get('/portfolio', function(req, res, next){
//call parse function in file xmlParser.js
xmlParser.parse(__dirname + "/xml/svn_log.xml", listJSON);
xmlParser.parse(__dirname + "/xml/svn_list.xml", logJSON);
console.log("middleware was excuted!");
next();
}, function(req, res){
console.log(listJSON);
});
现在这就是文件xmlParser.js
的样子,
//include the modules
var fs = require('fs'),
xml2js = require('xml2js'),
parser = new xml2js.Parser();
//this function parse xml file with name as filename to json and stores it in variable outputJSON
function parse(filename, outputJSON){
fs.readFile(filename, function(err, data){
if(err){
console.log('cannot read file.');
} else {
parser.parseString(data, function(err, result){
if(err) console.log('cannot parse file.');
else {
outputJSON = result;
}
});
}
});
}
module.exports = {
parse
}
现在,当我运行应用程序并转到路由/portfolio
时,我希望打印出来:
middleware was executed!
[object]
但这是我在节点控制台上获得的,
middleware was executed!
undefined
现在,我想要的是xmlParser.js
中的函数执行并将解析后的JSON对象存储在我传递给它的listJSON
对象中。当我将listJSON
作为第二个参数传递给parse()
函数时,是否通过引用传递?为什么我得到'undefined printed when my function in the file
xmlParser.js`会在其中存储一个对象?
答案 0 :(得分:1)
一个问题是您的parse
函数调用fs.readFile
和parser.parseString
是异步的。第二个问题是您更改了函数中的对象:JavaScript通过对象共享传递参数。含义:原始变量按值传递:更改参数不会更改源变量。非原始变量(如对象和数组)也不能更改,但它们的属性可以。
确实在调用parse
之前调用next
,异步读取文件,然后异步解析它(不阻止路由代码),使next
早于程序完成解析文件。
你可以做的是逐个管理你的异步动作,也让解析返回结果,你将在之后设置它。首先更改您的parse
函数以接受回调并调用它:
function parse(filename, callback){
fs.readFile(filename, function(err, data){
if(err){
console.log('cannot read file.');
return callback(err);
} else {
parser.parseString(data, function(err, result){
if(err) {
console.log('cannot parse file.');
return callback(err);
}
else {
return callback(null, result);
}
});
}
});
}
然后,将您的解析函数与next
函数一起管道:
app.get('/portfolio', function(req, res, next){
xmlParser.parse(__dirname + "/xml/svn_log.xml", function(err, list) {
listJSON = list;
xmlParser.parse(__dirname + "/xml/svn_list.xml", function(err, log) {
logJSON = log;
next();
});
});
console.log("middleware was excuted!");
}, function(req, res){
console.log(listJSON);
});