为什么VueUse里的useIntersectionObserver函数的回调函数内部可以调用stop()方法?

作者站长头像
站长
· 阅读数 13

前端小菜鸟一只,今天遇到了个大难题。业务需求是利用VueUse的useIntersectionObserver函数实现图片资源懒加载,但我比较困惑的地方是useIntersectionObserver函数的第二个参数是一个回调函数,为什么可以在这个回调函数里调用 stop() 来停止监听呢?我困惑的地方在于:赋值语句从右到左进行,先得到等号右边的结果再赋值给左边,调用stop()的时候等号左边还没有解构出 stop 这个方法呀。我在解构时尝试重新命名为 abc,回调函数内部调用 abc()程序仍正常运作,说明回调函数内调用的就是等号左边解构出的结果。虽然业务功能可以实现,但我不明白为什么可以这样写,希望好心人能指点一下为什么VueUse里的useIntersectionObserver函数的回调函数内部可以调用stop()方法?

我可以理解下面这种,返回值赋值给stop后调用stop()函数。(图片来自VueUse官网)为什么VueUse里的useIntersectionObserver函数的回调函数内部可以调用stop()方法?

回复
1个回答
avatar
test
2024-06-29

简单构建一下模拟的代码,就会发现,并不是所有情况下,都可以这样用。

比如下面的代码中,如果你把 setTimeout 换成同步的方式去调用(直接调用 cb),那就会出现两种情况。

  • 1、如果下面的解构获取是使用的 const,那就会报 “不能在变量初始化之前进行使用”
  • 2、如果下面的解构获取是使用的 var,那就会报 “abc 不是一个函数”

重要的点就在于,在执行这个 abc 时,这个变量是否已经拿到了值。

当使用同步执行的时候,实际上要走到后面的 return 才能把这里的 stop 给出去,这时候才有 stop 函数。

而当这个回调函数作为异步执行时,就不一样了,异步时,这里的函数已经执行完了,外面已经拿到返回值并解构赋值给了 abc。

在调用时,就会跟随其声明的域开始向上查找,找到对应的方法进行调用。

!(function () {
  function foo (el, cb) {
    setTimeout(cb) // 重要

    return {
      stop () {
        console.log('stop')
      },
    }
  }

  const { stop: abc } = foo('#app', () => {
    console.log(this)
    abc()
  })
})()
回复
likes
适合作为回答的
  • 经过验证的有效解决办法
  • 自己的经验指引,对解决问题有帮助
  • 遵循 Markdown 语法排版,代码语义正确
不该作为回答的
  • 询问内容细节或回复楼层
  • 与题目无关的内容
  • “赞”“顶”“同问”“看手册”“解决了没”等毫无意义的内容