大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。
Jetbrains全系列IDE使用 1年只要46元 售后保障 童叟无欺
问题描述
今天写一个取消收藏的功能遇到问题。
取消收藏的流程是这样的:点击取消收藏后会做unshare的请求对项目取消收藏,等请求结束后会弹出窗口提示成功取消,然后发送获取收藏的请求,更新收藏内容状态。这时候出现了一个问题,当我对一个项目进行取消收藏后,更新过来的内容里还是有我取消的那个项目。开始以为是取消收藏失败了,但刷新之后重新获取的收藏内容里又成功了。
通过多次尝试后发现,是因为取消收藏这个api太慢了,点击取消后获取全部收藏没能快速反应过来。
所以想到拿到total这个参数,然后判断请求过来的总数有没有变化,变化了在更新收藏内容。
异步拿到收藏
这样就得写两个effects了,刚进入收藏页面的时候通过api拿到所有收藏;然后点击取消收藏后,触发取消收藏api,这时候yield put到新的effects:aftergetcollection。
*aftergetcollection({
payload},{
call,put}){
//请求收藏的项目
let res
res=yield call(Middleware.getcollection,[payload[0],payload[1]])
let timer= setInterval(()=>{
if(res.data.total<payload[2]){
yield put({
type:'createcollection',
token:payload[1],
total:res.data.total,
payload:res.data.results,
page:"1",
})
}
},1000)
},
通过 setInterval 不断判断total是否比之前的少,如果判断正确跳到同步的createcollection,然后找一个时机 clearInterval() 就行了。
然而这样做肯定是不对的
编译器直接报错了。原因很简单,因为yield表达式只能用在 Generator 函数里面。那么在effects中就无法使用 setTimout() 和 setInterval() 这样的函数了。
在Effects中做循环
其实想要在models中做定时器和循环很简单,yield提供的put方法就是一个很好的循环方法,只需要对effects自身做put,就可以无限的循环了,但是循环的速度很快会对性能造成影响,所以接下来解决定时器的问题就可以了。
*aftergetcollection({
payload},{
call,put}){
//请求收藏的项目
let res
res=yield call(Middleware.getcollection,[payload[0],payload[1]])
if(res.data.total<payload[2]){
yield put({
type:'createcollection',
token:payload[1],
total:res.data.total,
payload:res.data.results,
page:"1",
})
}else{
//对effects自身put
yield put({
type:"aftergetcollection",
payload:payload
})
}
},
models的定时器的方法其实可以在外侧写,在顶部定义一个常量delay,然后在里面写一个setTimeout的方法
const delay = (timeout) => {
return new Promise(resolve => {
setTimeout(resolve,timeout)
})
}
然后在effects中call这个方法,设定延迟1秒就可以了
yield call(delay, 1000)
yield put({
type:"aftergetcollection",
payload:payload
})
完整代码:
const delay = (timeout) => {
return new Promise(resolve => {
setTimeout(resolve,timeout)
})
export default {
namespace:"collectioninfo",
state:{
...
},
effects:{
*aftergetcollection({
payload},{
call,put}){
//请求收藏的项目
let res
res=yield call(Middleware.getcollection,[payload[0],payload[1]])
if(res.data.total<payload[2]){
yield put({
type:'createcollection',
token:payload[1],
total:res.data.total,
payload:res.data.results,
page:"1",
})
}else{
yield call(delay, 1000)
yield put({
type:"aftergetcollection",
payload:payload
})
}
},
}
}
发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/188644.html原文链接:https://javaforall.cn
【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛
【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...