Javascript 读取多个文件后的回调函数
我正在做类似的事情 我正在做的是一次一个地读取所选文件的内容,以验证它们的行是否通过一些正则表达式测试。在验证完所有文件后,我需要相应地更新(启用/禁用)一些按钮,从而实现回调功能 是否有可能有一个回调函数,它将在读取所有内容后执行某些操作 HTML:Javascript 读取多个文件后的回调函数,javascript,jquery,html,file-io,Javascript,Jquery,Html,File Io,我正在做类似的事情 我正在做的是一次一个地读取所选文件的内容,以验证它们的行是否通过一些正则表达式测试。在验证完所有文件后,我需要相应地更新(启用/禁用)一些按钮,从而实现回调功能 是否有可能有一个回调函数,它将在读取所有内容后执行某些操作 HTML: Javascipt: 功能手柄文件选择(evt){ var files=evt.target.files;//文件列表对象 //文件是文件对象的文件列表。请列出一些属性。 var validArray=[]; for(var i=0,f;f
Javascipt:
功能手柄文件选择(evt){
var files=evt.target.files;//文件列表对象
//文件是文件对象的文件列表。请列出一些属性。
var validArray=[];
for(var i=0,f;f=files[i];i++){
//创建新的文件读取器
var r=新文件读取器();
//待命
r、 onload=(函数(f){
返回函数(e){
var内容=e.target.result;
变量行=contents.split('\n');
对于(var i=0;i我将查看jQuery的
这也是一个可能适用于您的非常相关的问题
绝对如此。回调只会像任何其他正常参数一样传递,因此我们最终会将另一个参数添加到handleFileSelect
,并将事件侦听器更改为一个匿名函数,该函数使用额外的参数调用handleFileSelect
我设置了一个演示程序,为您提供一个快速工作的演示
function handleFileSelect(evt, cb) {
var files = evt.target.files; // FileList object
// files is a FileList of File objects. List some properties.
var output = [];
for (var i = 0, f; f = files[i]; i++) {
output.push('<li><strong>'+ escape(f.name) + '</strong>');
}
document.getElementById('list').innerHTML = '<ul>' + output.join('') + '</ul>';
if(cb) cb();
}
document.getElementById('files').addEventListener('change', function(e){handleFileSelect(e, function(){alert('all done');})}, false);
功能手柄文件选择(evt、cb){
var files=evt.target.files;//文件列表对象
//文件是文件对象的文件列表。请列出一些属性。
var输出=[];
for(var i=0,f;f=files[i];i++){
push(''+escape(f.name)+'');
}
document.getElementById('list').innerHTML=''+output.join('')+'
';
if(cb)cb();
}
document.getElementById('files').addEventListener('change',函数(e){handleFileSelect(e,函数(){alert('all done');}}}),false);
分解它-在handleFileSelect
中添加了一个额外的参数,并在末尾添加了if(cb)cb();
。这只是检查cb是否存在,如果存在,则将其作为函数运行
然后,当我们绑定事件处理程序而不是传递对handleFileSelect
的引用时,我们使用了一个匿名函数——这让我们可以传递额外的参数
匿名函数中的匿名函数只是我们的回调函数,如果您愿意,它可以是对函数的引用。来这里寻找类似的答案。我想在加载和处理所有文件后调用函数。@Snuffleupagus提供的解决方案对我无效,因为该函数是在r所有文件都被读取了,但在onload函数中处理完之前,我找到了一个解决方案,如下所示(不确定它是否是“最干净的”,但它对我有效)
我尝试使用r.onloadend,但调用得太快。我相信这是因为我的函数“onLoadHandler”处理每个文件需要几秒钟,并且在文件加载完成时,但在“onload”中的代码运行完成之前,会调用onloadend。一个真正干净的方法是使用方法。提供了许多处理ith多个回调。您可以使用reduce遍历文件名数组,并构建一个reduce值,该值是一个有效行数组:
<input type="file" id="files" name="files[]" multiple />
<script type='text/javascript' src='https://github.com/caolan/async/raw/master/lib/async.js'/>
<script>
var isValidLine = function(text){
// todo: implement
}
function handleFileSelect(evt) {
var files = evt.target.files; // FileList object
// reduce by starting with empty array in second argument -
// this gets built up with the valid array lines
async.reduce(files, [], function(validLinesSoFar, file, callback){
var r = new FileReader();
// Read file here:
r.onload = function (f) {
var contents = f.target.result;
var lines = contents.split('\n');
for(var i=0; i<lines.length; i++){
if isValidLine(lines[i])
validLinesSoFar.push(lines[i]);
}
callback(null, validLinesSoFar);
};
r.readAsText(file);
}, function(err, validLines){
// gets called after every file iterated through
// result is entire valid array
// do something here with valid array
});
}
document.getElementById('files').addEventListener('change', handleFileSelect, false);
</script>
var isValidLine=函数(文本){
//todo:实现
}
功能手柄文件选择(evt){
var files=evt.target.files;//文件列表对象
//通过在第二个参数中以空数组开始减少-
//这是由有效的数组行组成的
async.reduce(文件,[],函数(ValidLinesFar,文件,回调){
var r=新文件读取器();
//在此处读取文件:
r、 onload=函数(f){
var内容=f.target.result;
变量行=contents.split('\n');
for(var i=0;代码与您认为的不一样。每次选择文件时,ul
将被清除并用完整的文件列表重写,该列表保存在输出
数组中(这正是您要查找的数组)。你想要实现的到底是什么?嗯。也许我简化了我的示例太多。我正在做的是一次一个地读取所选文件的内容,以验证它们的行是否通过一些正则表达式测试。验证完所有文件后,我需要更新(启用/禁用)相应地,我会用detailsAh sweet更新问题的一些按钮!这正是我想要的!谢谢!@Omar当然,只需为回调添加一个额外的参数,并用匿名函数包装事件侦听器来传递它。我尝试了这个变量readAndValidateCallback=function(e){readAndValidate(e,function(){alert('all done');}})但是它没有回调,你能修改一下我更新的代码吗?回调以前被调用过everything@Omar你是怎么想的?你的意思是在附加文本之前?
function handleFileSelect(evt, cb) {
var files = evt.target.files; // FileList object
// files is a FileList of File objects. List some properties.
var output = [];
for (var i = 0, f; f = files[i]; i++) {
output.push('<li><strong>'+ escape(f.name) + '</strong>');
}
document.getElementById('list').innerHTML = '<ul>' + output.join('') + '</ul>';
if(cb) cb();
}
document.getElementById('files').addEventListener('change', function(e){handleFileSelect(e, function(){alert('all done');})}, false);
var processedCount=0; // global variable
var totalFiles = 0; // global variable
function handleFileSelect(evt) {
var files = evt.target.files; // FileList object
totalFiles = files.length; // important
// files is a FileList of File objects. List some properties.
for (var i = 0, f; f = files[i]; i++) {
//Create new file reader
var r = new FileReader();
//On load call
r.onload = (function(theFile){
return function(){
onLoadHandler(this,theFile);
onLoadEndHandler();
};
})(f);
r.readAsText(f);
}
}
function onLoadEndHandler(){
processedCount++;
if(processedCount == totalFiles){
// do whatever - this code will run after everything has been loaded and processed
}
}
<input type="file" id="files" name="files[]" multiple />
<script type='text/javascript' src='https://github.com/caolan/async/raw/master/lib/async.js'/>
<script>
var isValidLine = function(text){
// todo: implement
}
function handleFileSelect(evt) {
var files = evt.target.files; // FileList object
// reduce by starting with empty array in second argument -
// this gets built up with the valid array lines
async.reduce(files, [], function(validLinesSoFar, file, callback){
var r = new FileReader();
// Read file here:
r.onload = function (f) {
var contents = f.target.result;
var lines = contents.split('\n');
for(var i=0; i<lines.length; i++){
if isValidLine(lines[i])
validLinesSoFar.push(lines[i]);
}
callback(null, validLinesSoFar);
};
r.readAsText(file);
}, function(err, validLines){
// gets called after every file iterated through
// result is entire valid array
// do something here with valid array
});
}
document.getElementById('files').addEventListener('change', handleFileSelect, false);
</script>