你好,欢迎来到潮汕IT智库!
您的位置:首页 > IT资讯> 热点新闻 热点新闻
副作用清理 onWatcherCleanup
2025-01-13 09:29:33 作者: (评论0条)

有时我们可能会在侦听器中执行副作用,例如异步请求:


watch(id, (newId) => {  fetch(`/api/${newId}`).then(() => {    // 回调逻辑  })})

但是如果在请求完成之前 id 发生了变化怎么办?当上一个请求完成时,它仍会使用已经过时的 ID 值触发回调。理想情况下,我们希望能够在 id 变为新值时取消过时的请求。


我们可以使用 onWatcherCleanup() API 来注册一个清理函数,当侦听器失效并准备重新运行时会被调用:


import { watch, onWatcherCleanup } from 'vue'
watch(id, (newId) => {  const controller = new AbortController()
  fetch(`/api/${newId}`, { signal: controller.signal }).then(() => {    // 回调逻辑  })
  onWatcherCleanup(() => {    // 终止过期请求    controller.abort()  })})

请注意,onWatcherCleanup 仅在 Vue 3.5+ 中支持,并且必须在 watchEffect 效果函数或 watch 回调函数的同步执行期间调用:你不能在异步函数的 await 语句之后调用它。


作为替代,onCleanup 函数还作为第三个参数传递给侦听器回调,以及 watchEffect 作用函数的第一个参数:


watch(id, (newId, oldId, onCleanup) => {  // ...  onCleanup(() => {    // 清理逻辑  })})
watchEffect((onCleanup) => {  // ...  onCleanup(() => {    // 清理逻辑  })})

这在 3.5 之前的版本有效。此外,通过函数参数传递的 onCleanup 与侦听器实例相绑定,因此不受 onWatcherCleanup 的同步限制。

总结

Vue 3.5+ 中支持 onWatcherCleanup() 注册一个清理函数,在当前侦听器即将重新运行时执行。只能在 watchEffect 作用函数或 watch 回调函数的同步执行期间调用 (即不能在异步函数的 await 语句之后调用)。


停止侦听器:

const stop = watch(source, callback)
// 当已不再需要该侦听器时:stop()


暂停/恢复侦听器:

const { stop, pause, resume } = watch(() => {})
// 暂停侦听器pause()
// 稍后恢复resume()
// 停止stop()


3.5+ 中的副作用清理:


import { onWatcherCleanup } from 'vue'
watch(id, async (newId) => {  const { response, cancel } = doAsyncWork(newId)  onWatcherCleanup(cancel)  data.value = await response})


在 setup() 或 


要手动停止一个侦听器,请调用 watch 或 watchEffect 返回的函数:


const unwatch = watchEffect(() => {})
// ...当该侦听器不再需要时unwatch()


注意,需要异步创建侦听器的情况很少,请尽可能选择同步创建。如果需要等待一些异步数据,你可以使用条件式的侦听逻辑:


// 需要异步请求得到的数据const data = ref(null)
watchEffect(() => {  if (data.value) {    // 数据加载后执行某些操作...  }})


每当被侦听源发生变化时,侦听器的回调就会执行。如果希望回调只在源变化时触发一次,请使用 once: true 选项。


相关文章
推荐 3 个令人惊艳的 GitHub 开...
Linux 操作必备 150 个命令,速...
副作用清理 onWatcherClean...
红帽RHEL将成为微软官方WSL发行版...