Appearance
异步和清理的具体例子
本节目标:理解“异步和清理的具体例子”的核心思路,并能把它用于实际开发或面试表达。 假设你正在构建一个邮件应用。用户可以在收件箱中选择一个邮件来阅读。你可能会写下面的代码来获取邮件的内容: import { ref, watch } from 'vue' const selectedMailId = ref(null) const mailContent = ref(null) watch(selectedMailId, async (newId, oldId, onCleanup) => { // 假设
fetchMailContent是一个返回 Promise 的函数,它会根据给定的 ID 获取邮件内容。 // 它返回一个对象,包含responsePromise 和cancel函数。 //cancel函数会取消请求(可能是调用了 Fetch API 的AbortController)。 const { response, cancel } = fetchMailContent(newId) // 当selectedMailId改变时,cancel将被调用,取消前一个未完成的请求 onCleanup(cancel) mailContent.value = await response })
在这个例子中,每次用户选择一个新的邮件阅读,我们都会开始一个新的请求来获取邮件内容。如果用户在请求完成之前选择了另一个邮件,我们会取消前一个请求。这样,我们就不会浪费时间和带宽去获取用户已经不再感兴趣的邮件的内容,也不会有任何未完成的请求。 当我们说 cancel "取消"一个请求时,实际上是在中断请求。在 Fetch API 中,这可以通过 AbortController 实现。这是一个简单的 fetchMailContent 函数的例子,展示了如何使用 AbortController: function fetchMailContent(id) { const controller = new AbortController() const response = fetch(/api/mails/${id}, { signal: controller.signal }) .then(response => response.json()) const cancel = () => controller.abort() return { response, cancel } } 在这个函数中,我们使用 AbortController 创建一个新的 signal,并将这个 signal 传递给 fetch。如果我们调用 controller.abort(),那么与这个 signal 关联的 fetch 请求将被中断。
axios例子 在 axios 中,取消请求的方式稍有不同,它是使用 CancelToken 来实现的。 下面是一个如何使用 axios 获取邮件内容的例子,其中也展示了如何取消请求: import axios from 'axios' function fetchMailContent(id) { const CancelToken = axios.CancelToken; const source = CancelToken.source(); const response = axios.get(/api/mails/${id}, { cancelToken: source.token }) .then(response => response.data) const cancel = () => source.cancel() return { response, cancel } }
在这个例子中,我们创建一个新的 CancelToken 源(source),并将其 token 传递给 axios.get。如果我们调用 source.cancel(),那么与这个 token 关联的 axios 请求将被取消。
接下来,我们可以将这个 fetchMailContent 函数用于 watch 的回调函数中,类似于上述 fetch API 的例子: import { ref, watch } from 'vue' const selectedMailId = ref(null) const mailContent = ref(null) watch(selectedMailId, async (newId, oldId, onCleanup) => { const { response, cancel } = fetchMailContent(newId) onCleanup(cancel) mailContent.value = await response }) 这样,每当用户选择一个新的邮件阅读,我们就会开始一个新的请求来获取邮件内容。如果用户在请求完成之前选择了另一封邮件,我们会取消前一个请求,确保我们的应用在用户的交互下响应迅速,而且不会产生任何未处理的请求。
