Thunk函数配合Generator函数使用,依次读取上传文件

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title></title>
	</head>
	<body>
		<button type="button">读取文件</button>
		<input type="file" id="fileinput"  multiple />
		<output id="outputfile"></output>
		
		<script type="text/javascript">
			let fi=document.getElementById("fileinput");
			let output=document.getElementById("outputfile");
			let reader;

			function readfile(file,cb){
				// var file=files[0];//获取上传的文件
				
					reader=new FileReader();//
					reader.readAsText(file);//读取文本
					reader.onload=function(e){
						//这个事件发生,意味着数据准备好了
						output.textContent=e.target.result;//将结果显示在标签里面
					};
					reader.onloadend=cb;
			}
			
			document.querySelector("button").onclick=function (){
			run(go);
			}
			
			function run(fn){
				let gen=fn();
				function next(err,data){
					let result=gen.next(data);
					if(result.done) return;
					setTimeout(() => {
						result.value(next);
					},5000)
				}
				next();
			}
			let ft=thunkify(readfile);
			
			function *go(){
				for(let i=0;i<fi.files.length;i++){
					yield ft(fi.files[i]);
				}
			}
			
			 function thunkify(fn){
				 return function(){
					 let args=new Array(arguments.length);
					 let ctx=this;
					 
					 for(let i=0;i < args.length; ++ i){
						 args[i] = arguments[i];
					 }
					 return function(done){
						 let called;
						 args.push(function(){
							 if(called) return;
							 called=true;
							 done.apply(null,arguments);
						 })
						 try{
						 	fn.apply(ctx,args);
						 }catch(e){
						 	//TODO handle the exception
							done(err);
						 }
					 }
				 }
			 }
		</script>
	</body>
</html>

/*
			 //thunkify是如何运行的呢?
			 // 接收一个函数f1,然后又返回一个函数f2,在这个f2中,先获取f1中参数,将这个参数保存在args中,
			 // 然后用这个ctx保证this为f2函数,再返回f3函数,这个函数接收一个回调函数done。在f3中,定义
			 // called来判断done是否被执行过,args.push中的匿名函数是用来包裹done的,调用这个函数则直接
			 // 执行了done(done.apply(null,arguments)就是这一句),并且将called定为true,防止多次执行回调。
			 // fn.apply(ctx,args);这句话的意思是把f1中的this替换为f2,同时把f2中保存的参数(也就是去掉f1中
			  // 回调函数之后的参数)传入,就等同于f1获取了全部参数,开始运行了
			  
			  //我觉得可以这么理解,f2就是一个壳子,里面装有f1中除了回调函数这个参数之外的参数,然后这个壳子又
			  //产生了另一个壳子f3,这个f3里面装了回调函数这个参数。当f3有了这个参数之后,圆满了。然后f3将这个回调
			  // 参数传给f2,f2又将全部参数传给f1,f1有了全部参数后可以运行了
			  // 参数进过层层剥离,实现了参数可分次输入的效果,这样就可以在有需要的时候再执行操作
			  
			 // 可能表述不太清楚,可以试试简单版本的
			  //Thunk函数简单实现==>只能将2个参数变为单参数
			  // const Thunk=function(fn){
			  // 	return function(...args){
			  // 		return function(callback){
			  // 			return fn.call(this,...args,callback);
			  // 		}
			  // 	}
			  // }
			  // function f(a,cb){
			  // 	cb(a);
			  // }
			  // const ft=Thunk(f);
			  // ft(1)(console.log);
			  // let one=ft(1);
			  // let two=one(console.log);
			  
			  //然后 run函数是如何运行的呢?
			  // 这个例子有点特别,就是这个回调函数就是本身,即这是个递归函数
			  // readfile接收两个参数,第一个是文件名,第二个是这个函数本身,这个本身又接收两个参数,第一个是
			  // 文件名......一直循环下去,直到不再传入回调函数为止,所以只需要一直传入文件名就可以,最后当不再传入
			  //文件名时即为停止
			  // 第一个next运行(第一个next参数被默认丢弃),返回对象的value属性的值是f2(ft(fi.files[i])是一个函数),
			  // 隔了5S,给这个f2传了参数(next函数),即执行,打印出第一个文件内容。然后一直这样循环下去,最后当yield不再
			  //产出f2时(就是文件名已经被全都输入了一遍),next方法返回对象的done为true,停止运行
*/

有什么不对的地方可以一起交流

喜欢的朋友可以点个赞啊

求关注一下我的公众号,谢谢啦

                                             

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值