回调函数和递归函数的基本用法

一.什么是回调函数?

简单说就是,你想在某个特定的时间点执行某些操作。

例如:张三跟女朋友吃完饭,对女朋友说到家记得发短信告诉我,女朋友然后回到家之后,给张三说:我到了,请放心。这个发短信这个事是提前说好的,这个动作就是回调函数。

模拟如上实例代码:

  function girl(boyname){
    alert(boyname+'我回到家了')
  }
//boy为主函数,girl函数作为参数传到boy中,girl就是我们所说的回调函数
  function boy(girl,name){
    alert('回到家记得告诉我')
    alert('女孩回家路上')
    girl(name)
  }

  boy(girl,"张三")

再例如:平时我们请求数据库的操作,然后返回的查询结果也是使用的回调函数。

模拟请求数据库操作:


// 在调用函数A时, 他的参数是另一个函数B, 此时函数B就是函数A的回调函数
setTimeout1(function(err, data){
    console.log("执行了setTimeout1的回调函数")
    if(err){
        console.log(err.message)
    }else{
        console.log(data)
    }
})


// 以下是 setTimeout1 函数的内部实现原理
function setTimeout1(callback){
    // 形参callback表示一个函数, 这个函数在调用setTimeout1时传入, 叫做回调函数
    // callback()
    // 使用随机数模拟, 数据库查询操作, 随机数<0.5说明查询失败  >=0.5说明查询成功
    if(Math.random()<0.5){
        callback({message:"查询失败,原因不详"}, null)
    }else{
        callback(null, "查询结果数据")
    }
}

二.什么是递归函数?

简单说,递归就是一次次的调用自身,当满足某个条件时,递归结束。

实例如:目录结构的展开和斐波那契数列

      // ------------------   (一)什么是递归? -----------------

        // 普通的函数
        function method1(){
            console.log("普通函数")
        }
        // 函数不会主动执行,需要被动调用才会执行, 而且必须在函数外部调用
        method1()
        // 递归函数 : 在函数内部调用这个函数自身, 形成一个调用循环
        function method2(){
            console.log("递归函数")
            // 如果一个函数的调用出现在这个函数内部, 那这个函数就叫递归函数
            // method2()
        }
        // 递归函数也必须在函数外部调用一次, 以进入递归循环
        method2()


        // --------------------- (二)递归如何使用? --------------
        // 向上边的写法, 递归函数很容易进入死循环
        // 一般递归函数有两种解决方案, 防止递归进入死循环报错
        // 1, 在函数内部调用函数自身时,不直接调用,而是用计时器调用, 可以防止报错
        function method3(){
            console.log("递归函数")
            setTimeout(method3, 100)
            // requestAnimationFrame(method3)
        }
        method3()
        // 2, 递归函数一般需要添加判断条件, 在不满足条件是,结束递归,防止死循环
        var count = 0;
        function method4(){
            console.log("递归" + count)
            count ++;
            if(count < 100){
                method4()
            }
        }
        method4()
        // ----------------------- (三)什么情况下使用递归? -------------
        // 1, 在使用requestAnimationFrame实现页面动画时, 要用递归调用
        // 2, 在处理多层嵌套数据时, 可能需要用到递归
        var array = [
            "一级标题A",
            "一级标题B",
            [
                "二级标题C",
                ["三级标题D", "三级标题E"],
                ["三级标题F", "三级标题G", '三级标题H', ["四级标题I"]]
            ]
        ]
        // 假设以上嵌套数组是一个不稳定的结构, 数组层数未知,数组结构有可能动态更新 
        function method5(arr){
            //在解决多层嵌套问题时, 递归函数一般有参数, 而且每次递归的参数都不同
            // 对数组遍历
            arr.forEach(item=> {
                // 判断这个数据是字符串还是数组
                if(typeof item == "string"){
                    document.writeln(item)
                }else{
                    // 既然item不是字符串,那肯定是数组, 接着继续遍历这个数组
                    method5(item)
                }
            });
        }
        method5(array)

        // 3, 求斐波那契数列第22位数字
        // 0、1、1、2、3、5、8、13、21、34、…  相邻两个数字的和为下一个数字
        var count = 1;
        function method6(x, y){
            count ++;
            if(count <= 22){
                method6(y, x + y)
            }else{
                console.log(x)
            }
        }
        method6(0, 1)

总结:如果要在特定时刻执行某些操作,就用回调,即主函数传参时传进一个函数名。

           如果要重复操作相同的事情时,请选择递归。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值