- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
出于各种原因,我正在将 Python 应用程序移植到 Node.js。我通过 Web 开发获得了一定的 Javascript 知识,但在变量范围和(可能?)我正在进行的一些异步调用方面遇到了一些问题。
因此,我的 DataLoader 类中有一个嵌套方法“xmlToObjectByType”,我试图根据一系列 XML 文件中的某些匹配条件在其中设置变量。无论我在方法中做什么,产品都不会从 null 改变,并且 xml_files.splice() 调用永远不会起作用。我确信这是一个范围问题(在 fs.readFile 内部的 parseString 中的代码,在 forEach 等内部) 但我还没有找到太多的运气来弄清楚到底为什么或如何正确获取设置的值。
作为最后的努力,我尝试在 xmlToObjectByType 上设置的回调中获取结果,这为我提供了我正在寻找的值,但我仍然无法从打回来。我确信这与范围界定有关,但我有点不知所措。我确信这是一件我忽略的非常简单的事情,但我已经很长时间没有深入研究 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>
最佳答案
Macmee 是正确的,因为您的 data
和 product
变量仅在异步调用的 xmlToObjectByType
回调范围内更改(在您请求将结果记录到控制台之后,处理器的下一个滴答声)。
但我认为您的主要问题不在于您对数据的处理,而在于您在代码中请求有关数据的反馈的时间点。
因此,在您当前的代码中,products
正在使用表示 XML 的对象进行填充,但它只是在您要求打印之后很久才进行填充回到你身边。您可以通过放置一个简单的定时函数来测试这个理论,该函数将在半秒内报告结果:
/* ... code before */
var working_directory = working_directory;
var xml_files = [];
var products = null;
var data = null;
setTimeout(function(){
console.log(products);
}, 500);
/* code after... */
因此,您真正想要的是一般情况下 DataLoader
的回调
:
function DataLoader(working_directory, callback){
并在 XML 解析回调中调用它:
xmlToObjectByType("products", function(result) {
callback({"products": result});
});
然后像这样调用您的DataLoader
:
DataLoader('/Path/To/XML', function(data){ console.log(data) });
通过对代码进行这些调整,我在控制台中得到以下输出:
{ products:
[ { Artist: [Object], Title: [Object], Description: [Object] },
{ Artist: [Object], Title: [Object], Description: [Object] },
{ Artist: [Object], Title: [Object], Description: [Object] },
{ Artist: [Object], Title: [Object], Description: [Object] }
]
}
显然我正在对您的用户案例做出一些假设。但我认为这演示了如何在异步 JavaScript 中导航不同的范围。
更新
下面是对应用程序的重写,它将整理多个 XML 文件中的数据,然后使用数据进行回调:
var fs = require('fs'),
xml2js = require('xml2js'),
path = require('path');
export function DataLoader (directory, callback) {
getXmlFiles( function (files) {
parseXmlFile(files, callback);
} );
function parseXmlFile (files, callback) {
var parser = new xml2js.Parser();
var data = {};
var filesLeft = files.length;
files.forEach( function(file, i) {
fs.readFile( path.join(directory, file), function (err, result) {
parser.parseString( result, function (err, result) {
if (result.Products.Product) {
var result_object = result.Products.Product;
if (result_object.length > 0 && result_object[0].Artist) {
data[file] = result_object;
}
}
filesLeft--;
if (!filesLeft)
callback(data);
});
});
});
}
function getXmlFiles (callback) {
var files = [];
fs.readdir(directory, function (err, f) {
if(err) throw err;
f.forEach( function (file) {
if (file.split('.').pop() == "xml") {
files.push(file);
}
});
callback(files);
});
}
}
将它与这样的东西一起使用:
DataLoader( __dirname, function (data) {
console.log(data);
});
关于javascript - Javascript 中嵌套函数 "Class"结构中的变量范围,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33769595/
所以我试图设置“内容”类的高度,但它似乎不起作用。我对嵌套 DIV 非常陌生,我已经尝试了我在谷歌搜索中发现的修复程序,但似乎没有任何效果。帮助?
好的,所以我一直在四处寻找,但找不到这个问题的答案。但是,我需要将一个 View 嵌套在另一个 View 中。 我有一个 $layout 正在使用我拥有的 default.layout Blade 文
好的,所以我一直在四处寻找,但找不到这个问题的答案。但是,我需要将一个 View 嵌套在另一个 View 中。 我有一个 $layout 正在使用我拥有的 default.layout Blade 文
基本上,我的问题很简单,但它需要知道 Struts 1.1 并且还活着的人。 我尝试构建的伪代码看起来像这样: IF element.method1 = true THEN IF element
我正在尝试将 Excel 嵌套 IF 语句转换为代码语言,但我不确定我是否正确执行此操作,希望能得到一些帮助 这是Excel语句: =IF(D3="Feather",IF(OR(I3>1000,R3=
如果我们创建两个或三个评论并对其进行多次回复,则“有用”链接在单击时会导致问题,它会对具有相同编号的索引执行 ng-click 操作,从而显示具有相同索引的所有文本。如何解决此嵌套问题,以便在单击链接
我在项目中使用Scala,想与Stripe集成,但它只提供Java API。例如,要创建 session ,我使用: val params = new util.HashMap[String, Any
以下代码有一个 Div,其中连续包含四个较小的 Div。四个 Div 中的每一个还包含一个较小的 Div,但此 Div 未显示。我尝试了各种显示和位置组合,看看 div 是否会出现。 classGoa
我在这里有一个问题,循环是: for (i=0; i < n; ++i) for (j = 3; j < n; ++j) { ...
我正在尝试编写代码来显示具有奇数宽度的形状。形状完成后,将其放置在外部形状内。用户将能够输入用于形状的字符和行数。我希望生成一个形状,并通过 for 循环生成一个外部形状。 ***** .
$(".globalTabs").each(function(){ var $globalTabs = $(this); var parent = $globalTabs.parent
关闭。此题需要details or clarity 。目前不接受答案。 想要改进这个问题吗?通过 editing this post 添加详细信息并澄清问题. 已关闭 9 年前。 Improve th
所以我在这个问题上遇到了一些麻烦,因为变量 i。我只是不确定在第二个 while 循环中如何处理它。对于我的外循环,我知道它将运行 log_4(n^2) 次迭代。对于内部 while 循环,我计算的迭
我似乎找不到在枚举上应用多个 if/then 逻辑的工作方式。 anyOf 不应用条件逻辑,而是表示如果其中任何一个匹配则很好。 allOf 再次不应用条件逻辑,而是测试属性/必填字段的超集。 这是一
如何访问 ReaderT 的内部 monad。 在我的例子中,我有类型: newtype VCSSetupAction a = VCSSetupAction (ReaderT (Maybe VCSCo
这个问题在这里已经有了答案: Add leading zeroes/0's to existing Excel values to certain length (7 个回答) 7年前关闭。 我正在寻
我已经绑定(bind)了很多 AND/OR 函数的组合并且没有运气。 这是我需要创建的: 在 B 列中,我有公司 ID,范围从两个数字字符到六个数字字符。 我需要在 B 列中的每个公司 ID 之前的每
我是 VBA 新手,在尝试编写的宏中使用 If 语句时遇到了一些困难。每个月我都会收到一份 Excel 报告,其中列出了我们公司的哪些员工执行了某些任务。我正在编写的宏旨在将每个员工的数据复制并粘贴到
如果在 B 列中找到单元格 A1 中的值,则使用文本 321 填充除非在 C 列中找到单元格 A1 中的值,在这种情况下填充文本 121反而。如果单元格 A1 的内容不在 B 列或 C 列中,则使用
我有几十万个地址。其中一些在整数之后有粒子。如 4356 A Horse Avenue , 其他格式正常4358 Horse Avenue .有些有“A”,有些有“B”。我正在尝试删除整数和粒子之间的
我是一名优秀的程序员,十分优秀!