您的位置:首页 > Web前端 > JavaScript

javascript递归的实际应用场景

2018-01-10 19:56 393 查看
递归是各种书里经常讲到的东西,但是今天才在工作中遇到合适的使用场景,用过一次之后对他的理解也更具体了,在这里整理一下。

递归

递归的概念简单来说,就是在函数里边调用函数本身。

比如一个阶乘函数:

function factorial (n) {
if(n === 1){
return
}
return n * factorial(n-1)
}
factorial(5)


尾递归

但是像上边那样递归会保存很多个调用帧,比如上边的
factorial(5)
,这个方法要执行5次,才能返回最终的计算表达式,这样每次都要保存这个方法,就容易造成栈溢出。为了解决这个问题,我们会使用尾递归:

function factorial (n, total=1) {
if(n === 1){
return total
}
return factorial(n-1, n * total)
}
factorial(5)


这样,每一次返回的就是一个新的函数,不带上一个函数的参数,也就不需要储存上一个函数了。只需要一个帧即可。

工作中的使用场景

回到正题,工作中其实不太会经常让你求个阶乘啥的。递归的使用场景也就比较少,但是今天让我遇到一个,就赶紧记下来:使用循环发送ajax请求

实际场景是这样的,我维护的table列表组建,做了一个表头筛选的功能。其中就需要获取筛选项,当有多个筛选项数组都需要从后台获取的时候,就需要循环数组发送ajax请求,但是由于ajax是异步的。多个请求就无法正常处理返回。

所以使用递归,在ajax的回调中重新调用他:

// data是配置对象的数据
// 通过data[currentIndex ],currentIndex++来循环
var data = [obj1,obj2,obj3]
var currentIndex = 0
var sendAjax = function () {
// 结束递归的条件,不然就无限循环下去了。
if(currentIndex >= data.length){
return
}
// 获取ajax所需的参数
var config = data[currentIndex],
postMethod = config.postMethod || 'doGet',
postData = config.postData || {},
path = config.getOptsPath,
$th = self.$thead.find('th[filter-name="' + config.filterName + '"]')
// 发起请求
Common[postMethod](path, postData, function (res) {
// 回调中增加currentIndex
currentIndex++
// 处理请求数据
var filterDataParseMode = config.filterDataParseMode
var data = self.filterDataParse(res, filterDataParseMode)
var content = self.theadFilterRender({
data: config,
options: data
})
$th = self.$thead.find('th[filter-name="' + config.filterName + '"]'),
$th.html(content);
$th.find('ul').find('li:first').addClass('gridList-filter-active');
// 请求数据处理结束后递归,再一次请求
sendAjax()
}, function(rej){
// 失败也要继续递归,这样才不影响其他的请求。
currentIndex++
sendAjax()
})
}
sendAjax()
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  js 递归