前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >javascript undefined_setvalidator

javascript undefined_setvalidator

作者头像
全栈程序员站长
发布2022-09-27 11:09:54
7710
发布2022-09-27 11:09:54
举报
文章被收录于专栏:全栈程序员必看

大家好,又见面了,我是你们的朋友全栈君。

问题描述

今天写一个取消收藏的功能遇到问题。

取消收藏的流程是这样的:点击取消收藏后会做unshare的请求对项目取消收藏,等请求结束后会弹出窗口提示成功取消,然后发送获取收藏的请求,更新收藏内容状态。这时候出现了一个问题,当我对一个项目进行取消收藏后,更新过来的内容里还是有我取消的那个项目。开始以为是取消收藏失败了,但刷新之后重新获取的收藏内容里又成功了。

通过多次尝试后发现,是因为取消收藏这个api太慢了,点击取消后获取全部收藏没能快速反应过来。

所以想到拿到total这个参数,然后判断请求过来的总数有没有变化,变化了在更新收藏内容。

异步拿到收藏

这样就得写两个effects了,刚进入收藏页面的时候通过api拿到所有收藏;然后点击取消收藏后,触发取消收藏api,这时候yield put到新的effectsaftergetcollection

代码语言:javascript
复制
 *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,就可以无限的循环了,但是循环的速度很快会对性能造成影响,所以接下来解决定时器的问题就可以了。

代码语言:javascript
复制
 *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的方法

代码语言:javascript
复制
const delay = (timeout) => { 
   
  return new Promise(resolve => { 
   
    setTimeout(resolve,timeout)
  })
}

然后在effectscall这个方法,设定延迟1秒就可以了

代码语言:javascript
复制
  yield call(delay, 1000)
             yield put({ 
   
               type:"aftergetcollection",
               payload:payload
             })

完整代码:

代码语言:javascript
复制
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
             })
           }
    },
}
}

发布者:全栈程序员栈长,转载请注明出处:https://javaforall.cn/188644.html原文链接:https://javaforall.cn

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 问题描述
  • 异步拿到收藏
  • 在Effects中做循环
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档