watch模拟副作用并清除副作用

220 阅读1分钟

使用 Vue 3 的 watch 函数来监视 id 的变化,并在 id 变化时执行异步操作,同时取消之前未完成的请求。下面给出一个具体的例子来解释这段代码的用法:

import { watch, ref } from 'vue';

const data = ref(null);

// 模拟一个异步操作,返回一个 Promise 和一个取消函数
function doAsyncWork(id) {
  return new Promise((resolve, reject) => {
    const timeout = setTimeout(() => {
      resolve(`Data fetched for ID ${id}`);
    }, 2000);

    const cancel = () => {
      clearTimeout(timeout);
      reject(new Error('Request canceled'));
    };

    return { response: resolve, cancel };
  });
}

const id = ref(1);

watch(id, async (newId, oldId, onCleanup) => {
  console.log(`Watching new ID: ${newId}, old ID: ${oldId}`);

  const { response, cancel } = doAsyncWork(newId);

  onCleanup(cancel); // 取消之前的未完成请求

  try {
    const result = await response;
    data.value = result;
    console.log('Data fetched:', result);
  } catch (error) {
    console.error('Error:', error.message);
  }
});

// 改变 id 来触发 watch 函数
id.value = 2; // 这会取消之前的请求并重新请求新的数据

在这个例子中,我们定义了一个 id 和一个 data 的响应式变量,并使用 watch 监听 id 的变化。每当 id 变化时,会执行回调函数,其中会调用 doAsyncWork 来模拟异步请求,并传入 onCleanup 函数以取消之前的未完成请求。当新的数据请求完成后,将相应的数据赋值给 data 变量。

当我们修改 id 的值时(例如从 1 改为 2),watch 将会取消之前的未完成请求,并重新发起新的数据请求。这样可以确保只有最新的请求结果会反映到 data 变量中,避免数据混乱或重复请求的情况发生。