ajax闭包问题及反思

ajax闭包问题及反思


啥话也别说,直接上代码

function subData(){
	var pList = [];
	//设置成功函数
	if(!("success" in defaultAjaxParam)){
		defaultAjaxParam.success = (data) => {
   			if(data.flag){
				if ("dataList" in data){
					var dataList = data["dataList"];
						for (var i=0;i<dataList.length;i++) {
							pList.push(dataList[i]);
						}
					}
   			}else{
   				alert(data.msg);
   			}
		}
	}
	
	//ajax请求
	$.ajax(defaultAjaxParam);
	return pList;
}

其中的defaultAjaxParam如下所示

//全局变量
var defaultAjaxParam = {
  type:"POST",
  url:"con.do",
  async:false,
  dataType:'json',
  data:{},
  error: function (data) {
    alert("网络连接不稳定");
  }
};

$.fn.updataPictureList(options){
	...//此处省略代码
	
	//更新ajaxParam
	if("ajaxParam" in options){
		$.extend(defaultAjaxParam,options.ajaxParam);
	}
	
	subData();
}

非常简单的一个ajax返回函数,为了加强其功能性,我又对它初步进行了封装,同时利用全局变量增加了记忆功能

但是问题也随之而来了,使用这个加强版的ajax时,第一次可以正常运行,第二次时返回为空!

我百思而不得其解,使用了前端的调试工具,一行行调试;发现当第二次运行时,ajax.success中的pList和subData中的pList虽然名称一样,但却好像2个值(虽然名称一样,但是修改任意一个,另外一个都没有反应)

第一次调用:
在这里插入图片描述
第二次调用:
在这里插入图片描述
很明显,第二次调用的还是第一次的变量,导致第二次的返回值直接为空!

其实这个问题非常简单,第二次调用却使用的第一次的变量,没有按照我的要求重新生成,导致了第二次中没法获取第一次的变量

我优先想到的是,这可能是js隐含的坑,于是专门去查了一下,这种在函数内部定义函数并传值的方法叫做闭包;其作用就是能扩大变量的作用域

明白原理了,问题还是要解决,尝试了闭包中的各种解决方案,比如在外层套个匿名函数,将值取出来重新放到其它数组,其中具体的方法我就不赘述了,无非是百度"js 闭包"这样的字符串然后按照上面的文档做罢了

足足6个小时,文章读了十几篇,问题还是没解决

实在翻不动了,休息一会时突然想到:
这个问题综合一下就是上次的变量作用域被扩大多了,直白点就是它在应该生命周期结束时没有结束生命周期;虽然我不知道js引擎是怎么实现闭包的,但是这就是一个GC问题,它不回收,我强行给他回收不就完事了?

于是,果断将它赋值为空,创建一个临时变量做中转将值传递出去.果然,问题搞定

突然有些感慨:学习更底层的技术,就是为了不让别人的代码捆住自己的手脚

但是这只是折中之法,我后面又专门问了大佬,大佬看了5分钟代码,然后和我说:你seccess判断第二次没执行

!?!..(这就是我和大佬的差距吗?QwQ)

原因其实很简单,第一次添加了seccess函数,但是ajaxParam是一个全局参数,第二次调用时检测到有seccess函数,所以就没有添加,导致第二次根本没有形成闭包!

而我的"强制删除"生效的原因是:当js遇到一个变量时,会优先在本地寻找该变量,没找到则去更高层寻找,闭包所形成的变量是在最里层的,js寻找时,会优先使用它;但我把它强制删除后,js在本地找不到同名变量,不得不向上层找

虽然是一个非常简单的问题,但是其中涉及到GC,作用域,闭包等多个方面的问题,所以我就把它写了出来,希望这篇文章能对你解决问题的思路有所启发.

最后,我平时不怎么写文章,所以可能出现词不达意的地方,还请大家多多包涵

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值