通过递归的方式解决ajax循环请求的问题

问题描述

最近在做音乐类型的H5页面,音乐数据后台发布只提供了ID,然后针对ID进行发送ajax请求,往往我们在做H5应用的时候,ID都是一个列表,要展示一个列表的音乐,这个时候遇到了一个问题 :

问题:

ajax请求还没返回数据,循环已经完成,导致在我们绑定DOM事件的时候DOM还没生成无法绑定事件。

开始的代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
var dataArry = [1111,2222,3333,4444,5555]
function loopDate(){
var h = '';
$.map(dataArry, function(item, index) {
$.get("loadAjax", { item:item }, function (d) {
h+='<span></span>'
});
$('#music-info').html(h);
$('span').on('click',function(){
//TODO
})
});
}
loopDate()

上面的伪代码可能存在一些问题,我们先来解决,存在的问题就是会循环的绑定‘click’事件,意思就是时间重复绑定,如果要解决这个问题,我们用一个变量来判断,只在循环最后进行dom时间绑定:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
var dataArry = [1111,2222,3333,4444,5555]
function loopDate(){
var h = '';
var cont = 0
$.map(dataArry, function(item, index) {
$.get("loadAjax", { item:item }, function (d) {
h+='<span></span>'
});
$('#music-info').html(h);
if(count == dataArrt.length - 1){//解决重复绑定的问题
$('span').on('click',function(){
//TODO
})
}
});
}
loopDate()

上面的代码当我们运行的时候并不能正确的插入到页面中“span”标签并没有插入到页面,从而绑定事件就无从说起了

解决方案1:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
var dataArry = [1111,2222,3333,4444,5555]
function loopDate(){
var h = '';
var count = 0
$.map(dataArry, function(item, index) {
$.get("loadAjax", { item:item }, function (d) {
h+='<span></span>';
if(count == dataArrt.length - 1){//解决重复绑定的问题
$('#music-info').html(h);
$('span').on('click',function(){
//TODO
})
}
count++
});
});
}
loopDate()

我们将 $(‘#music-info’).html(h) 放在请求里面,注意这种方法有一个问题,就是dom会随机的绑定比如可能存在的问题比如:

11111

22222

44444

33333

55555

还有一个问题就是代码也不清晰,并且重复的操作DOM插入影响性能。

这并不是我们想要的,在我们做音乐的过程中可能对用户数据排列要求不高的话,可以这样做,要是我们在做排行榜类似的应用的时候我们就不能这么做了

解决方案2:运用递归

正好我们有一个count是为了解决重复绑定的问题,我们将其提出去
然后我们把循环去掉,就变成这样:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
var dataArry = [1111,2222,3333,4444,5555];
var count = 0;
var h = '';
function loopDate(count,dataArry){
if (index < array.length) {
$.get("loadAjax", { item:item }, function (d) {
h+='<span></span>'
loopDate(count+1,dataArry)
});
if(count == dataArrt.length - 1){//解决重复绑定的问题
<!-等待所以数据加载完成后插入 -->
$('#music-info').html(h);
$('span').on('click',function(){
//TODO
})
}
}
}
loopDate(count,dataArry)

上面一种就是相对比较完善的解决方案!

解决方案3:

我们知道在这里需要进行事件绑定,其实我们不用绑定到具体的DOM上,可以通过事件委托来进行处理具体的方案可以参考我之前的一篇文章:

使用事件代理来优化dom事件的绑定

如果对您有所帮助或者对博主有更多的话说,欢迎你去我的GitHub留下一个您的start和issues

前往LEE的github给他一个Start鼓励一下吧

[原创转载请标注出处:https://leehongqiang.github.io]