微信小程序开发——连续快速点击按钮调用小程序api返回后仍然自动重新调用的异常处理

前言:

  小程序开发中诸如获取用户手机号码、调起微信支付、领取卡券等api都是会有一定的延迟的。也就是说通过点击按钮调用这些api的时候,从点击按钮调用api,到支付页面或者领取卡券界面展示出来是需要一定时间的,连续点击按钮,还是有可能会重复调用的。

  虽然这种情况有点极端,正常用户是不会这么连续快速的点击按钮的,但是也不能排除有用户手抖,连续点了两下。如果重复调用的话,不仅体验不好,单击事件中涉及到后端接口操作的也可能引起其他异常。所以这个问题还是要处理下的。

  刚开始想到的是使用loading开启模板来防止点击穿透,结果发现loading从调用到蒙板起作用也是需要一定时间的,还是解决不了这个问题(自定义loading加蒙板防点击穿透应该可以的)。后边就想到了采用给按钮添加启用/禁用状态来控制按钮点击的频率——点击按钮,按钮状态设置为禁用,一定时间之后,启用按钮可用状态。经多次验证,此法可行。

处理方法:

1. 设置按钮可用状态:

Page({
  data: {
    disabled: false //购买按钮是否可用,按钮默认可用,点击一次后置为不可用,一定时间之后恢复可用
  },
  /**
   * 购买按钮点击防重:禁用/启用
   */
  buyBtnDisable: function() {
    this.setData({
      disabled: true
    })
    var self = this
    setTimeout(function() {
      self.setData({
        disabled: false
      })
    }, 1000)
  }
})

在每一个调用小程序api的按钮单击事件中先调用这个函数,则一定时间之内,这个按钮是禁用状态,就不会再重现重复点及的问题了。

2. 自定义loading:

创建模板或组件loading,在页面中直接使用该模板替代微信loading组件就好了,由于:

loading.wxml

<template name="loading">
<view class='loading'>
<view class='bg'>
  <image src='https://lg-gc2dnftu-1257370699.cos.ap-shanghai.myqcloud.com/timg.gif' width="100" height="100"></image>
 </view>
</view>
</template>

loading.wxss

.loading{
  position: absolute;
  top:0;
  left:0;
  width:100%;
  height:100%;
}
.bg{
  background: rgba(0,0,0,0.7);
  width:200rpx;
  height:200rpx;  
  margin:50% auto;
  border-radius: 10rpx;
  padding-top:70rpx;
  box-sizing: border-box;
}
.loading image{
  display: block;  
  width:60rpx;
  height:60rpx;
  margin:0 auto;
}

这样就可以使用自定义loading替代微信小程序原生loading了,经验证,此方法能解决多次点击按钮重复调用api的问题。

关于模板具体使用详见:https://www.cnblogs.com/xyyt/p/9559326.html

结语:

  经验证,上边两种方法都能有效解决按钮连续点击重复调用微信api的问题,且两种方法都需要放在单击事件的开头在单击事件中先行运行。

  采用设置按钮状态的方法比较独立,只需要在单击事件开头就调用函数就好,函数会在指定时间之后恢复按钮的可点击状态,不会对后续代码有太大影响(但是这种方法会暂时屏蔽按钮的启用状态,指定时间内再次点击是无效的)。

  采用自定义loading方式是使用蒙版覆盖了按钮,本质上未对按钮做任何修改,只是在loading展示的期间无法点击而已。缺点就是在后续的代码中关闭loading,loading的关闭也是需要一定时间的。如果是调用获取用户手机号码授权的api,取消授权的时候关闭loading,则会在取消之后,loading还会显示一下再消失,体验有点不太好。

综上,上边两种方法各有优劣,可以根据自己的需要选择使用。

后续改进:

2018.9.27  

1. 鉴于方法1会直接改变按钮的可点击状态,设置禁用时间过短则无效,过长则会导致一定时间内按钮点击无反应,而且这个时间不好确定,故选用自定义loading方法;

2. 对loading组件进行改进,新增了 transparent 来控制loading组件加载图标及其半透明的模块背景的显隐:

  之所以有这个改进,是针对单击事件中同时有后端接口访问和微信api调用的情况。一般loading是针对服务器端接口访问进行使用的——调用接口之前显示loading,接口响应成功,loading关闭。但如果在调用服务器端接口成功之后需要同步调用微信小程序的api,如下单之后需要调起微信api进行支付,那么在调起微信支付前后也是要使用loading做下蒙板来防止重复点击按钮。

  在调用小程序api的过程中直到支付界面展示出来,loading消失,这个过程中,按钮被loading的蒙板挡着,可以有效的防止重复点击。但是对于获取手机号码授权及微信支付都是以弹窗的形式展示的,所以在调用小程序api直到弹窗弹出的过程中,loading是会一直展示的,这样体验就不太好了。解决这个问题,比较好的就是隐藏掉loading的菊花图标及半透明层,也就是仅充当一个透明蒙板来使用,这样即能防止按钮重复点击,也不影响展示。

组件模板代码:

<view class='loading'>
  <view class='bg' wx:if="!transparent">
    <image src='https://lg-gc2dnftu-1257370699.cos.ap-shanghai.myqcloud.com/timg.gif' width="100" height="100"></image>
  </view>
</view>

调用页面业务逻辑代码:

 1 Page({
 2   data: {    
 3     loading: false, //默认不显示loading
 4     transparent: false //默认显示loading加载图标,设置为true,则只有蒙板,看不到loading图标
 5     ...
 6   },
 7   /**
 8    * 调用微信小程序api的单击事件
 9    */
10   clickEventRequestMpaPI: function() {
11     //调用服务器端api显示loading
12     this.setData({
13       disabled: true
14     })
15     //调用服务器端api(请求方法已封装)
16     http.paymentOrder(prams).then(data => {
17       if (data) {
18         //调用服务器端api关闭loading
19         self.setData({
20           loading: false
21         })
22         var d = data;
23         self.orderId = d.orderNo;
24         //发起微信支付
25         //调用微信支付api显示透明无图标的loading
26         self.setData({
27           loading: true,
28           transparent: true
29         })
30         wx.requestPayment({
31           ...
32           'success': function(data) {
33             //4.1.1查询支付结果                        
34             ......
35           },
36           'fail': function(err) {
37             console.log("requestPayment fail:::", err)
38           },
39           'complete': function(res) {
40             //调用微信支付api关闭透明无图标的loading
41             self.setData({
42               loading: false,
43               transparent: false
44             })
45           }
46         })
47       }
48     })
49   }
50   ...
51 })

原创专业博客,转载请注明来源地址:https://www.cnblogs.com/xyyt/p/9708770.html

posted on 2018-09-26 19:42  逍遥云天  阅读(2400)  评论(0编辑  收藏  举报

导航