利用闭包向post回调函数传参数
2016-09-27 11:18
88 查看
最近在闲逛XX站的时候,打算搞个破坏,试试有多少人还是用初始密码登陆。比较懒,所以直接打开控制台来写。
所以问题可以描述为:
向后端不断的post数据,id从1~5000自增,后端会根据情况来返回值res,需要把res=100的id输出。
最简单的想法是:for循环内部调用post数据
但是,运行结果是这样的:
post函数时异步的进行请求,拿到请求之后才会执行回调函数。for循环执行速度要快于post函数的执行速度。当执行post之后,for循环不会等待post拿到res并执行回调,而是继续遍历,for循环几百几千次的速度都快于post。所以当第一个post请求去执行其回调时,循环已经结束,i=92500。
这和一道很经典的笔试题很像:
解决办法:利用闭包
相关解释:
通过把回调写成匿名函数闭包,将i变量保存并且立即调用函数,但是为了获取到返回的data数据,所以在闭包内部return function(data),用来作为真正的回调函数接受返回参数res-data
当执行完for循环之后,console.log()首先能拿到正常返回数据data的值,因为js里函数访问参数时访问的作用域不是当前作用域,而是函数声明环境下的作用域,所以就可以直接访问到每个res=100对应的循环变量i。
所以上面那个面试题的一种解法就是:
对函数的一些理解:
1.函数可以作为参数传入,参与运算。
2.函数可以保存内部数据的状态,常见通过构造函数内部var变量实现类的私有成员
3.还没想好怎么说,以后再补
转自:http://www.cnblogs.com/limingxi/p/4048705.html
写在最后:
上文中提到的匿名函数的闭包的参数值 i
如果是数值或字符串,没有问题。如果参数值为对象或数组,不知道会是什么情况?请兄弟们告诉我。
结果如下:
以上结果不难看出,如果参数为对象或数组时,只是修改了其值,并没有改变引用的地址,对于闭包来说,是同一个变量(只是里边的值不一样面已)。使用前多加注意。
当然兄弟们估计还有更好的方法,请告知。
所以问题可以描述为:
向后端不断的post数据,id从1~5000自增,后端会根据情况来返回值res,需要把res=100的id输出。
最简单的想法是:for循环内部调用post数据
//错误示范 一 for(var i = 92000;i<92500;i++){ //直接借用一下网站内引用的jq $.post("login.php", { ts:"login",username: i, password: i},function(data){ if(data=="100"){ console.log(i); } }); }
但是,运行结果是这样的:
post函数时异步的进行请求,拿到请求之后才会执行回调函数。for循环执行速度要快于post函数的执行速度。当执行post之后,for循环不会等待post拿到res并执行回调,而是继续遍历,for循环几百几千次的速度都快于post。所以当第一个post请求去执行其回调时,循环已经结束,i=92500。
这和一道很经典的笔试题很像:
for(var i = 0;i<10;i++){ setTimeout(function(){ console.log(i); },1000); } //输出结果为10个 10
解决办法:利用闭包
//利用闭包和返回函数实现 for(var i=92000;i<92500;i++){ $.post("index.php?action=login",{ ts:"login",username: i, password: i,chekcode:9895 },(function(i){ return function(data){ if(data == "100"){ console.log(i) } } })(i); ); }
相关解释:
通过把回调写成匿名函数闭包,将i变量保存并且立即调用函数,但是为了获取到返回的data数据,所以在闭包内部return function(data),用来作为真正的回调函数接受返回参数res-data
当执行完for循环之后,console.log()首先能拿到正常返回数据data的值,因为js里函数访问参数时访问的作用域不是当前作用域,而是函数声明环境下的作用域,所以就可以直接访问到每个res=100对应的循环变量i。
所以上面那个面试题的一种解法就是:
for(var i = 0;i<10;i++){ (function(i){setTimeout(function(){ console.log(i); },1000)})(i); }
对函数的一些理解:
1.函数可以作为参数传入,参与运算。
2.函数可以保存内部数据的状态,常见通过构造函数内部var变量实现类的私有成员
3.还没想好怎么说,以后再补
转自:http://www.cnblogs.com/limingxi/p/4048705.html
写在最后:
上文中提到的匿名函数的闭包的参数值 i
//利用闭包和返回函数实现 for(var i=92000;i<92500;i++){ $.post("index.php?action=login",{ ts:"login",username: i, password: i,chekcode:9895 },(function(i){ return function(data){ if(data == "100"){ console.log(i) } } })(i); ); }
如果是数值或字符串,没有问题。如果参数值为对象或数组,不知道会是什么情况?请兄弟们告诉我。
结果如下:
var h = {f:""}; function a(c){ (function(d) { setTimeout(function() { console.log(d); }, 1000) })(c); } h.f = "fuck1"; a(h); h.f = "fuck2"; a(h); h.f = "fuck3"; a(h); h.f = "fuck4"; a(h); /* 以上结果,输出四次fuck4 */ var h = [0]; function a(c){ (function(d) { setTimeout(function() { console.log(d); }, 1000) })(c); } h[0] = 1; a(h); h[0] = 2; a(h); h[0] = 3; a(h); h[0] = 4; a(h); /* 以上结果,输出四次[4] */
以上结果不难看出,如果参数为对象或数组时,只是修改了其值,并没有改变引用的地址,对于闭包来说,是同一个变量(只是里边的值不一样面已)。使用前多加注意。
当然兄弟们估计还有更好的方法,请告知。
相关文章推荐
- 广度/宽度优先搜索(BFS)详解
- UMG 研究之ScaleBox
- __strong typeof(self) strongself = weakself
- 各种网站汇总
- Java中网关支付时候私钥加密原因
- 使用devstack安装openstack过程中遇到的一些错误及解决办法
- DCL双检查机制
- Cure 打表
- java中的==、equals()、hashCode()
- 数据库表空间大小查询
- MPEG4与.mp4
- 修改Push动画样式
- swift 去除数组里面重复的属性
- mysql分区
- latch: cache buffers chains导致CPU冲高的问题
- 第五周项目4 —— 数制转换
- c++ 与C#比较
- NoSQL数据库_MongoDB_MongoDB 文档与集合
- redis 相关命令
- @using (Html.BeginForm())参数示例