vue3中watchEffect的副作用描述与防抖功能的实现

1,237 阅读1分钟

正文

watchEffect简单来说就是指名监视哪个属性,监视的回调中用到哪个属性,那就监视哪个属性。
但是它会有一个副作用。举个简单的例子就是,当你监听一个input的值,一旦值改变就调用一次接口,那么我们多次改变值时对应的接口请求也是多次的,这就会造成性能浪费。而在watchEffect里面进行监听触发接口时,如果该接口还没请求完,但是input值已经变更了,那么我们就要把这个未完成的接口(异步任务)清除掉,进而调用一个新的接口。
是的,简单来说副作用就是未完成的异步任务(包括setTimeout等)
因此清除副作用就是清除掉未完成的异步任务进而调用下一次的watchEffect

嗅觉灵敏的人就会发现,所谓的清除副作用就跟防抖里面的清除定时器变量一个道理。
所以我们可以用watchEffect来实现防抖机制,代码如下:
PS:onInvalidatewatchEffect回调函数里面的参数,作用就是清除副作用。

<script setup>
import { ref, watchEffect } from "vue";
let input = ref(0);
const getData = function(){
  return new Promise((resolve)=>{
      resolve('返回的数据');
  })
}
const stop = watchEffect((onInvalidate)=>{
  console.log('input的值增加了,将调用接口',input.value);
  let timer = setTimeout( async() => {
    let res = await getData();
    console.log(res)
  },2000);
  // 清除副作用:onInvalidate
  onInvalidate(()=>{
    clearTimeout(timer);
    console.log('接口还没调用成功 input的值有变动了 取消接口请求 再次触发watchEffect');
    if(input.value>9) clearInterval(inter);
  })
})

let inter = setInterval(()=>{
  input.value++;
},1000)

// 停止监听
onBeforeUnmount(() => {
  stop();
})
</script>