回调函数和回调地狱

139 阅读2分钟

回调函数

  • 回调函数 本质上就是一个普通函数
  • 一个函数A以实参的形式传递到函数B中
  • 在函数B中,以形参的方式调用函数A
  • 此时 函数A就可以称为 函数B的回调函数
  • 回调函数的使用场景为异步代码的解决方案
    /*function A() {
      console.log('我是函数A')
    }
    function B(callback) {
      callback()
    }
    B(A)*/

    // 基础版
    /*function fn(callback = () => {}) {
      console.log('让人帮忙去买水')
      setTimeout(() => {
        console.log('买到水了')
        callback()
      }, 3000)
    }
    function jinnang() {
      console.log('再帮忙买一箱水')
    }
    fn(jinnang)*/

    // 网络请求模拟
    function fn(chenggong, shibai) {
      const timer = Math.ceil(Math.random() * 3000)
      console.log('帮忙去买瓶水')
      setTimeout(() => {
        if(timer > 2500) {
          console.log('买水成功,用时', timer)
          shibai()
        } else {
          console.log('买水成功,用时', timer)
          chenggong()
        }
      }, timer)
    }
    fn(
      () => {console.log('开玩笑的,退了吧')},
      () => {console.log('买不到就别回来了')}
    )

回调地狱

  • 这不是我们写代码的时候出现的某个漏洞
  • 只是我们在利用回调函数解决问题的时候,代码量多了之后的一个视觉体验
    • 回调地狱的代码不利于我们去维护或者管理
    • 此时出现了一个东西叫做promise,也是一个异步代码的解决方案
     // 调用fn 函数 A就回去 买水
    function fn(chenggong, shibai) {
      const timer = Math.ceil(Math.random() * 3000)
      console.log('让A帮忙去买瓶水')
      setTimeout(() => {
        if(timer > 200) {
          console.log('买水成功,用时', timer)
          shibai()
        } else {
          console.log('买水成功,用时', timer)
          chenggong()
        }
      }, timer)
    }
    /**
     * 需求:
     *    在A买水失败后,让他再次去买水(重新调用fn函数)
     * 
     * 新需求: 
     *    如果A第二次也失败了,让他继续去买水
     * 
     * 新需求:第一次买水成功的时候,让A再去买一箱饮料
     * */ 
    fn(
      () => {
        fn(
          () => {console.log('A买完水后,又买了一箱饮料')},
          () => {console.log('A就买了一瓶水,他不愿意给你们买饮料')}
        )
      },
      () => {
        fn(
          () => {console.log('A第二次买水 成功了')},
          () => {
            fn(
              () => {console.log('A第二次买水 成功了')},
              () => {console.log('A第二次买水 失败了')}
            )
          }
        )
      }
    )