我正在构建一个接收文件名列表的webapp,并根据该输入读取文件,连接它们,并在各种图表中显示数据。这里很棘手的事情是在提取相关信息之前文件相当大(~6-10mb),而且我不确切知道用户会请求多少。 (假设一个典型的请求将大于3但小于20。)
就我所知,用d3读取任意数量的文件没有明显的方法。 Mike Bostock回答了类似的问题here。这些解决方案的问题在于它们需要您提前知道文件的数量 - 我没有那么奢侈。
我想做的是有一些递归函数,如:
function concatFiles(fileNameArray) {
function recursiveConcat(fileNameArray, concatedFile) {
var temp;
if (fileNameArray.length === 0) {
return concatedFile;
} else {
d3.csv(fileNameArray.shift(), function(err, csv) {
temp = csv;
}
return recursiveConcat(fileNameArray, concatedFile.concat(temp));
}
}
return recursiveConcat(fileNameArray, []);
}
这种解决方案的优点在于我不必为每个文件创建变量或将中间结果存储在数组中。但是,我不确定这个东西会不会很好地与Javascripts的异步性质(我是Javascript的新手)。如何有效地在arrayOfFileNames -> concatenatedFile
之间进行映射?
答案 0 :(得分:1)
d3-queue
似乎完全没问题。以下代码段应足以处理任意数量文件的加载:
function loadFiles(files) {
// Create a new queue to handle the loading of all files.
var q = d3.queue();
// Iterate over the array of all files to be loaded.
files.forEach(function(f) {
// Add a loading task for each file to the queue.
q.defer(d3.csv, f)
});
// When all loading tasks have finished, you may process the
// contents of all files.
q.awaitAll(function(error, contents) {
// Do your concatenation here.
// contents contains an array of the parsed results of all files
// console.log(contents);
})
}
var filesToLoad = ["file1.csv", "whatever.csv", "another.csv"];
loadFiles(filesToLoad); // load all files in the array
请注意,这不会对数组filesToLoad
中的文件数做出任何假设。请查看此Plunk以获取有效工作示例。