解决异步方法无法正常获取值的问题
本文由 小茗同学 发表于 2016-07-22 浏览(4247)
最后修改 2018-01-25 标签:异步 方法 传值 html5 文件上传 function bind

本文发表于:2014-06-19

以HTML5浏览本地多个文件为例

比如下面的例子,fileReader读取文件是异步的,等到fileReader的onload执行完毕时,临时变量i和file都不是正确的那个值,所以需要再嵌套一层function,将file和i传进去再return。

<input type="file" id="file" multiple/>
<script type="text/javascript">
document.getElementById('file').addEventListener('change', function()
{
	for(var i=0; i<this.files.length; i++)
	{
		var file = this.files[i];
		var fr = new FileReader();
		// 之所以外面嵌一层function是因为onload方法是异步执行的,传统写法等到执行里面代码时i早已经遍历完了
		fr.onload = (function(file, i)
		{
			return function(e)
			{
				console.log(i, file, this, e); // this==fr
				var dataURL = this.result; // 或者e.target.reslut也可以
			};
		})(file, i);

		//错误写法:
		//fr.onload = function(e)
		//{
		//	console.log(i, file, this, e);//此时i已经遍历完了,i和file都不是我们想要的值
		//}

		fr.readAsDataURL(file);
	}
});
</script>

当然,还有一个很简单的方法,就是使用ECMAScript5提供的Function.prototype.bind方法:

<input type="file" id="file" multiple/>
<script type="text/javascript">
document.getElementById('file').addEventListener('change', function()
{
	for(var i=0; i<this.files.length; i++)
	{
		var file = this.files[i];
		var fr = new FileReader();
		fr.onload = function(i, file, e)
		{
			console.log(i, file, this, e);
		}.bind(fr, i, file);
		fr.readAsDataURL(file);
	}
});
</script>