Java自学者论坛

 找回密码
 立即注册

手机号码,快捷登录

恭喜Java自学者论坛(https://www.javazxz.com)已经为数万Java学习者服务超过8年了!积累会员资料超过10000G+
成为本站VIP会员,下载本站10000G+会员资源,会员资料板块,购买链接:点击进入购买VIP会员

JAVA高级面试进阶训练营视频教程

Java架构师系统进阶VIP课程

分布式高可用全栈开发微服务教程Go语言视频零基础入门到精通Java架构师3期(课件+源码)
Java开发全终端实战租房项目视频教程SpringBoot2.X入门到高级使用教程大数据培训第六期全套视频教程深度学习(CNN RNN GAN)算法原理Java亿级流量电商系统视频教程
互联网架构师视频教程年薪50万Spark2.0从入门到精通年薪50万!人工智能学习路线教程年薪50万大数据入门到精通学习路线年薪50万机器学习入门到精通教程
仿小米商城类app和小程序视频教程深度学习数据分析基础到实战最新黑马javaEE2.1就业课程从 0到JVM实战高手教程MySQL入门到精通教程
查看: 767|回复: 0

小程序:前端防止用户重复提交&即时消息(IM)重复发送问题解决

[复制链接]
  • TA的每日心情
    奋斗
    2024-11-24 15:47
  • 签到天数: 804 天

    [LV.10]以坛为家III

    2053

    主题

    2111

    帖子

    72万

    积分

    管理员

    Rank: 9Rank: 9Rank: 9

    积分
    726782
    发表于 2021-4-25 09:49:39 | 显示全部楼层 |阅读模式

     

    背景:

    最近参与开发的小程序,涉及到即时消息(IM)发送的功能;

    聊天界面如下,通过键盘上的【发送】按钮,触发消息发送功能

     

     

     

    问题发现:

     功能开发完毕,进入测试流程;测试工程师反馈说:

     

    在Android手机上,在极短的时间内频繁点击键盘上的【发送】按钮,消息会重复发送;IOS上该问题不太明显

     

    本以为是普通的防重复提交问题,于是自然想到通过设定flag/js加锁的方式解决该问题,于是开始优化代码:

     

    项目基本代码:

     

    wxml:

    <input type="text" value="{{msgValue}}"  confirm-type="send" bindconfirm="sendMsg" bindinput="bindKeyInput" placeholder="请输入聊天内容" />
    

      

    JS:

      bindKeyInput(e) {
            this.setData({
                msgValue: e.detail.value.replace(/^\s+|\s+$/g, "")
            });
        },
        sendMsg() {
            let self = this;
            let msg = self.data.msgValue;
            if (msg && self.data.sendMsgState) {
                self.data.sendMsgState = false
                app.globalData.nim.sendText({
                    scene: 'p2p',
                    to: self.data.doctorId,
                    text: msg,
                    done(error, msg) {
                        if (!error) {
                            //消息发送成功
                            self.setData({
                                msgValue: ''
                            })
                        } else {
                            //消息发送失败
                            wx.showToast({
                                title: '消息发送失败,请稍后再试',
                                icon: 'none',
                                duration: 1500,
                                mask: true
                            })
                        }
                    }
                })
            }
        }
    

      

     

    1# 设定flag/js加锁

     

    //在页面初始数据data中,声明“锁”: sendMsgState
    
    data: {
        sendMsgState: true
    }
    
    //在发送消息方法中,符合消息发送条件的时候,把sendMsgState的值置为false;
    //并在消息发送成功之后,将消息发送框的value置空的之后,将sendMsgState设为true
    sendMsg() {
            let self = this;
            let msg = self.data.msgValue;
            if (msg && self.data.sendMsgState) {
                self.data.sendMsgState = false
                app.globalData.nim.sendText({
                    scene: 'p2p',
                    to: self.data.doctorId,
                    text: msg,
                    done(error, msg) {
                        if (!error) {
                            //消息发送成功,置空输入框;然后把sendMsgState重新设置为true
                            self.setData({
                                msgValue: ''
                            }, () => {
                                self.data.sendMsgState = true
                            })
                        } else {
                            //消息发送失败
                            wx.showToast({
                                title: '消息发送失败,请稍后再试',
                                icon: 'none',
                                duration: 1500,
                                mask: true
                            })
                        }
                    }
                })
            }
        }
    

      

    测试结果:

     Android手机上依然存在该问题,且很容易复现。

     

    分析原因:

    在极短的时间内,频繁点击键盘上的发送按钮;此时:锁(sendMsgState)还没来得及置为false,发送内容输入框的值还没有被清空;

    但发送事件已经被有效触发多次,导致了发送消息的重复。

     

     

    2# 在方案一设定flag/js加锁的基础上,增加连续点击按钮事件间隔少于1s,或者连续两次发送内容相同都停止发送的补充规则

     

        2.1:增加连续点击按钮事件间隔少于1s

                 经验证:正常的消息发送使用流程,连续两次的消息发送间隔都是超过1s的;间隔小于1s的行为,可判定为重复提交:

                具体做法:

                步骤一:在data中注册lastSendTime,设置值为空;触发发送事件sendMsg的时候,把当前时间保存到变量currentTime;

          步骤二:判断当前时间currentTime与上次发送时间的差值是否小于1000;如果是,则发送事件连续触发时间短于1s,停止发送;

                步骤三:消息发送成功之后,在置空内容输入框的setData回调方法中,将lastSendTime的值更新为:currentTime;

     

       2.2:如果当前发送的消息内容和上一次保存在data中的msgValue相同,则可判断连续两次消息重复

                 因为每次发送成功,data中msg都会被置空;而内容为空的时候,又是不允许发送的;

                 所以,在短时间内,如果当前发送的消息内容和上一次保存在data中的msgValue相同,则可判断连续两次消息重复

     

     

    最终优化方案:

     

       sendMsg() {
            let self = this;
            let msg = self.data.msgValue;
            // 防止两次点击操作间隔太快
            let currentTime = new Date();
            if ((currentTime - this.data.lastSendTime < 1000) || (msg === self.data.msg)) {
                //发送事件连续触发时间短于1s,或连续两次发送内容相同,则返回
                return;
            }
            if (msg && self.data.sendMsgState) {
                self.data.sendMsgState = false
                app.globalData.nim.sendText({
                    scene: 'p2p',
                    to: self.data.doctorId,
                    text: msg,
                    done(error, msg) {
                        if (!error) {
                            self.setData({
                                msgValue: ''
                            }, () => {
                                self.data.sendMsgState = true
                                self.data.lastSendTime = currentTime
                            })
                        } else {
                            //消息发送失败
                            wx.showToast({
                                title: '消息发送失败,请稍后再试',
                                icon: 'none',
                                duration: 1500,
                                mask: true
                            })
                        }
                    }
                })
            }
        }
    

      

    综上所述:

    在单一的flag/js加锁无效的情况下;通过添加额外的规则补充校验,最终方案如下:

     

     
    在发送内容msg有效及flag/js锁为true的基础上;
    发送事件sendMsg连续两次触发时间间隔大于或等于1s,及连续两次发送内容不相同的情况下,才允许消息被发送;
     

     

     

     最终测试结果:无论是Android,还是IOS都可以正常发送消息,无消息重复发送情况发生了

     

     

    哎...今天够累的,签到来了1...
    回复

    使用道具 举报

    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    QQ|手机版|小黑屋|Java自学者论坛 ( 声明:本站文章及资料整理自互联网,用于Java自学者交流学习使用,对资料版权不负任何法律责任,若有侵权请及时联系客服屏蔽删除 )

    GMT+8, 2025-1-24 07:04 , Processed in 0.063517 second(s), 30 queries .

    Powered by Discuz! X3.4

    Copyright © 2001-2021, Tencent Cloud.

    快速回复 返回顶部 返回列表