我正在尝试使用@pinia/nuxt和nuxt 3构建一个计时器。我还想在计时器启动时发出一个http请求来同步我的数据库。
我面临的问题是,每当我调用动作start
时,setInterval
的每次迭代都会发出http请求,而我只想运行一次。
这是pinia模块。我正在从组件中的onClick
事件调用start
操作。
state: () => ({
timer: {
id: null,
isRunning: false,
time: 5,
timer: 0,
state: null,
} as Timer,
}),
actions: {
start() {
this.timer.isRunning = true
this.syncTimer()
if (!this.timer.timer) {
this.timer.timer = setInterval(() => {
if (this.timer.time > 0) {
this.timer.time--
} else {
clearInterval(this.timer.timer)
this.reset()
}
}, 1000)
}
},
stop() {
this.timer.isRunning = false
clearInterval(this.timer.timer)
this.timer.timer = 0
},
reset() {
this.stop()
this.timer.time = 1500
},
syncTimer() {
backendAPI<Timer>('/api/timer', {
method: 'POST',
body: this.timer
}).then(({ error, data }) => {
if (!error.value) {
const id = data.value?.id ?? ""
this.timer.id = id
this.timer.state = "created"
}
})
}
}
字符串
自定义提取可组合backendAPI.ts
:
import type { UseFetchOptions } from 'nuxt/app'
import { useUserStore } from '@/stores/user'
import { defu } from 'defu'
export function backendAPI<T>(url: string, options: UseFetchOptions<T> = {}) {
const config = useRuntimeConfig()
const { token } = useUserStore();
const appToken = useRuntimeConfig().public.appToken
const defaults: UseFetchOptions<T> = {
baseURL: config.public.baseURL ?? 'http://localhost:4000',
key: url,
params: {
token: appToken
},
headers: token
? { Authorization: `Bearer ${token}` }
: {},
}
const params = defu(options, defaults)
return useFetch(url, params)
}
型
2条答案
按热度按时间kwvwclae1#
正如我在评论中提到的,实现实时特性的正确方法是使用套接字。但是,如果你需要以轮询的方式来做,你可以写一个guard,类似这样:
字符串
希望这对你有帮助。
niknxzdl2#
问题似乎与nuxt 3
useFetch
函数有关。从nuxt documentation:
所有的fetch选项都可以被赋予一个计算值或引用值。这些将被监视,如果它们被更新,则会自动使用任何新值发出新请求。
因此,每次更新计时器值时,
useFecth
都会自动发出一个新的请求。在请求中添加
watch: false
解决了我的问题字符串