利用闭包向post回调函数传参数
最近在闲逛XX站的时候,打算搞个破坏,试试有多少人还是用初始密码登陆。比较懒,所以直接打开控制台来写。
所以问题可以描述为:
向后端不断的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]
*/
以上结果不难看出,如果参数为对象或数组时,只是修改了其值,并没有改变引用的地址,对于闭包来说,是同一个变量(只是里边的值不一样面已)。使用前多加注意。
当然兄弟们估计还有更好的方法,请告知。
利用闭包向post回调函数传参数的更多相关文章
- [js]利用闭包向post回调函数传参数
最近在闲逛校园XX站的时候,打算搞个破坏,试试有多少人还是用初始密码登陆.比较懒,所以直接打开控制台来写. 所以问题可以描述为: 向后端不断的post数据,id从1~5000自增,后端会根据情况来返回 ...
- scrapy回调函数传递参数
scrapy.Request 的callback传参的两种方式 1.使用 lambda方式传递参数 def parse(self, response): for sel in response.xpa ...
- Chrome和Firefox浏览器执行new Date() 函数传参数得到不同结果的陷阱
某日,同事问到关于new Date() 函数传参数,在火狐浏览器和谷歌浏览器控制台运行,会得到不同的结果,刚开始觉得不可能,后来实际操作才发现此陷阱 var date = new Date('2014 ...
- 关于main函数传参数的问题
argc是命令行总的参数个数 argv[]是argc个参数,其中第0个参数是程序的全名,以后的参数 命令行后面跟的用户输入的参数,比如: int main(int ...
- 解决有关flask-socketio中服务端和客户端回调函数callback参数的问题(全网最全)
由于工作当中需要用的flask_socketio,所以自己学习了一下如何使用,查阅了有关文档,当看到回调函数callback的时候,发现文档里都描述的不太清楚,最后终于琢磨出来了,分享给有需要的朋友 ...
- PHP之回调函数传参(解决eval函数拼接对象参数的问题)
在使用Smarty时,定义了一个统一调用控制器的函数,如下: function C($name, $method){//控制器的名称和其中方法的名称 require_once "contro ...
- 利用call与apply向函数传递参数
Js中函数对象都有call与apply两个方法属性,二者使用方法和功能一样,只是传递参数的格式不同,call逐个传递单个参数,apply一次性传递一个参数数组. 这两个方法可以改变函数的调用对象,并且 ...
- 利用模块加载回调函数修改PE导入表实现注入
最近整理PE文件相关代码的时候,想到如果能在PE刚刚读进内存的时候再去修改内存PE镜像,那不是比直接对PE文件进行操作隐秘多了么? PE文件在运行时会根据导入表来进行dll库的"动态链接&q ...
- javascript 利用匿名函数对象给你异步回调方法传参数
先来创建一个匿名函数对象: /*** * 匿名函数 */ var callChangeBtn=new function(bugBtn){ this.chage=function(json){ bugB ...
随机推荐
- 进程状态转换、CPU调度算法
进程的状态转换 进程在运行中不断地改变其运行状态.通常,一个运行进程必须具有以下三种基本状态. 进程状态 执行态run:进程正在使用CPU 等待态wait:进程正在等待I/O完成,不在使用也不能使用C ...
- 免费好用的web应用托管平台-续
上一篇博客给大家推荐了目前处于免费阶段的PAAS平台,可以托管各种应用,大家反响很不错,说明大家还是很需要和认可这个免费托管各种web应用的京东云擎平台.但是很多用户还是很担心未来可能还是会收费,对于 ...
- Hibernate中使用的集合类型
department与employee是一对多关系. set <set name="emps" inverse="true"> <key co ...
- servlet tomcat servlet debug常见错误404,405,500
404 web服务器根据请求地址找不到对应资源 1,地址错误 2,web.xml文件中的两个<servlet-name>不一致 3,工程没有部署 4,web应用程序部署结构没有遵守serv ...
- js笔记:匿名函数
;(function(){ alert('啥也没做');})(); 会弹框. 这是个匿名函数.最前面的分号可以去掉,仅仅是在代码压缩时防止出错. 该函数可以拆解成非匿名函数: var a= funct ...
- Atitit。如何实现dip, di ,ioc ,Service Locator的区别于联系
Atitit.如何实现dip, di ,ioc ,Service Locator的区别于联系 1. Dip原则又来自于松耦合思想方向1 2. 要实现dip原则,有以下俩个模式1 3. Ioc和di的 ...
- atitit.重装系统需要备份的资料总结 o84..
atitit.重装系统需要备份的资料总结 o84.. 这里我的系统装在C盘..所以需要备份C盘的东西就好了.. 1.DESKTOP,这个目录要备份.如果重要资料 2.docume nt,这个需要..W ...
- atitit. java queue 队列体系and自定义基于数据库的队列总结o7t
atitit. java queue 队列体系and自定义基于数据库的队列总结o7t 1. 阻塞队列和非阻塞队列 1 2. java.util.Queue接口, 1 3. ConcurrentLink ...
- 迅美VPS安装和配置MySQL数据库教程
MySQL相关教程与知识: 迅美VPS安装和配置MySQL数据库教程 navicat8管理MySQL教程-创建数据库和导入数据 navicat8管理MySQL教程-管理建立用户和分配 ...
- 用DOS批处理实现FTP自动上传、下载、清理文件
用DOS批处理实现FTP自动上传.下载.清理文件 最近好像特别的忙,好久没来写点东西了,今天写了一个利用批处理程序完成FTP自动上传.下载.清理文件的程序.赶紧 记录下来,以备日后之用.功能介绍:自动 ...