【发布时间】:2016-02-19 13:42:22
【问题描述】:
因此,出于各种原因,我正在将 Python 应用程序移植到 Node.js。我通过 Web 开发获得了适度的 Javascript 知识,但在变量范围和(可能?)我正在进行的一些异步调用方面遇到了一些问题。
所以,我的 DataLoader 类中有一个嵌套方法“xmlToObjectByType”,我试图根据一系列 XML 文件中的一些匹配条件来设置变量。无论我在该方法中做什么,产品都不会从 null 更改,并且 xml_files.splice() 调用永远不会起作用。我很肯定这是一个范围界定问题(在 fs.readFile 中的 parseString 中的代码,在 forEach 中等等),但我找不到太多运气来弄清楚究竟是为什么或如何正确获取值集。
最后,我尝试在 xmlToObjectByType 上设置的回调中获取结果,这得到了我正在寻找的值,但我仍然无法从回调中设置 products 的值。我确定这与范围界定有关,但我有点茫然。我确信这是我忽略的一件非常简单的事情,但是自从我深入研究 JS 以来已经有很长时间了。这根本不是很深。除了可能很糟糕的逻辑流程之外,对我在这里做错了什么有任何想法吗?
请注意,这是一个简化版本,出于易读性原因,我在其中检查了一些其他 XML 文件类型。
代码
var fs = require('fs'),
xml2js = require('xml2js');
export function DataLoader(working_directory){
var working_directory = working_directory;
var xml_files = [];
var products = null;
var data = null;
var xmlToObjectByType = function(type, setValue) {
xml_files.forEach(function(file, index) {
var parser = new xml2js.Parser();
fs.readFile(working_directory + '/' + file, function(err, data) {
parser.parseString(data, function (err, result) {
if (result.Products.Product) {
var result_object = result.Products.Product;
// check if we've got at least one row, else return false
if (result_object.length > 0) {
// products specific check
if (type == "products") {
// identify products XML with artist tag
if (result_object[0].Artist) {
// this is a products XML file, so pop this file from xml_files, return object
xml_files.splice(index, 1);
setValue(result_object);
}
}
} else {
// no rows in object
setValue("no rows");
}
} else {
// ROW object isn't set, malformed XML
setValue("malformed XML");
}
});
});
})
}
// check selected directory for XML files
fs.readdir(working_directory,function(err,files){
if(err) throw err;
files.forEach(function(file){
// do something with each file HERE!
if (file.split('.').pop() == "xml") {
xml_files.push(file);
}
});
// if they don't exist return and send message
if (xml_files.length < 1) {
var status = {status: "error", message: "There are no XML files in the directory you selected."};
} else {
// process further
xmlToObjectByType("products", function(result) {
products = result;
});
data = {"products": products};
// products always has the value null here
console.log(data);
}
return status;
});
};
我是通过
import { DataLoader } from './my_module';
DataLoader('/Path/To/XML');
还有一个 XML 文件的简化示例(我认为我做对了)
<?xml version="1.0" encoding="UTF-8" ?>
<Products>
<Product>
<Artist>Test</Artist>
<Title>Test Title</Title>
<Description>Maecenas faucibus mollis interdum. Donec sed odio dui. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus. Aenean lacinia bibendum nulla sed consectetur. Cras mattis consectetur purus sit amet fermentum.</Description>
</Product>
<Product>
<Artist>Test</Artist>
<Title>Test Title</Title>
<Description>Maecenas faucibus mollis interdum. Donec sed odio dui. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus. Aenean lacinia bibendum nulla sed consectetur. Cras mattis consectetur purus sit amet fermentum.</Description>
</Product>
<Product>
<Artist>Test</Artist>
<Title>Test Title</Title>
<Description>Maecenas faucibus mollis interdum. Donec sed odio dui. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus. Aenean lacinia bibendum nulla sed consectetur. Cras mattis consectetur purus sit amet fermentum.</Description>
</Product>
<Product>
<Artist>Test</Artist>
<Title>Test Title</Title>
<Description>Maecenas faucibus mollis interdum. Donec sed odio dui. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus. Aenean lacinia bibendum nulla sed consectetur. Cras mattis consectetur purus sit amet fermentum.</Description>
</Product>
</Products>
【问题讨论】:
标签: javascript node.js asynchronous scope