美文网首页全栈汇总小细节 好产品@产品
对支付宝产品细节的提一个小小建议

对支付宝产品细节的提一个小小建议

作者: _onePiece | 来源:发表于2017-07-02 13:36 被阅读189次

    原由

    问题的原由很简单,就是我在使用支付宝花呗功能是,由于网络慢的原因重复点击了我的账单和我的额度时,出现页面重复加载的情况。点击次数和加载次数是相同的(我点击了5次跳了5次),并且是可以稳定复现的。但是这个小bug,说实话,无足轻重,完全不影响使用,更不会误导用户。
    大概是去年11月我是发现过微信的一个导致app卡死的bug,当时没有什么头绪,后来也就放弃思考没有记录,至今懊恼不已。所以这次本着发现问题解决问题不逃避的想法,还是把这个写下来。虽然很easy,但求不被拍砖。

    支付宝.png

    原因

    其实问题的原因很容易就猜到,是在花呗页面点击我的账单是,app请求数据,但是由于网络的原因,接受数据大概延迟了两秒。而在这期间我以为有什么问题,所以点击了五次。在接受数据时,点击事件由于没有检测的原因而执行了5次,于是页面跳转了5次。
    其实这个问题我自己在开发过程中也是发现过好几次,比如在亚程旅游iOSapp的自由行城市选择中,由于数据量大且有多个接口,会使用户明显感觉到延迟,用户在animation动画出现前快速点击两次,会有出现重复跳转的情况。直到这会儿才总结这个问题,惭愧。以前我是加个bool值来判断是否执行,我觉得这是很简洁明了的。但是如果有同样的情况又将要写重复的代码,所以将这个无论多少次点击跳转页面且执行一次的功能写成category。

    解决方案

    方案一外部阻止处理点击事件

    通过bool值来判断是否执行过。代码量比较少就贴下了。

    @interface UIView (delay)
    @property (nonatomic, copy) dispatch_block_t oneTapBlock;
    @property (nonatomic, assign) BOOL taskShouldBeCanceled;
    @end
    
    @implementation UIView (delay)
    - (void)setOneTapBlock:(dispatch_block_t)oneTapBlock{
        oneTapBlock();
    //**细节在这里
        self.taskShouldBeCanceled = YES;
    }
    - (dispatch_block_t)oneTapBlock{
        return self.oneTapBlock;
    }
    - (void)setTaskShouldBeCanceled:(BOOL)taskShouldBeCanceled{
    //**细节在这里
        objc_setAssociatedObject(self, @"taskShouldBeCanceled", @(!taskShouldBeCanceled), OBJC_ASSOCIATION_RETAIN_NONATOMIC);
    }
    - (BOOL)taskShouldBeCanceled{
        return [objc_getAssociatedObject(self, @"taskShouldBeCanceled") boolValue];
    }
    @end
    
    #import "BaseViewController.h"
    #import "UIView+delay.h"
    
    @interface BaseViewController ()
    @property (nonatomic, strong) UIButton *button;
    @end
    
    @implementation BaseViewController
    
    - (void)viewDidLoad {
        [super viewDidLoad];
        _button = [[UIButton alloc] initWithFrame:CGRectMake(100, 100, 100, 50)];
        _button.backgroundColor = [UIColor redColor];
        [self.view addSubview:_button];
        [_button addTarget:self action:@selector(click) forControlEvents:UIControlEventTouchUpInside];
    }
    
    - (void)click {
        __weak typeof(self) weakSelf = self;
        if (!_button.taskShouldBeCanceled) {
            _button.oneTapBlock = ^{
              //只需要将点击事件代码写在这里就可以
                UIViewController *vc = [[UIViewController alloc] init];
                vc.title = [NSString stringWithFormat:@"%@", @(arc4random() % 10)];
                [weakSelf.navigationController pushViewController:vc animated:YES];
            };
        }
    }
    @end
    
    方案二内部阻止处理点击事件

    这个感觉比较困难,因为要在block内部检测自己是否已经被执行过,在跳转页面的这种情况可以通过当前viewcontroller来决定执行block内的点击事件。但是如果要在block内部来取消自己,感觉这是比较困难的,如果各位大神有什么好的想法恳求不吝赐教。

    引申支付宝单车扫描

    在使用的过程中我感觉,支付宝的扫描速度是要略微比微信慢的。一般微信点击后感觉都没有开始扫描就已经识别二维码,然后请求数据了。而支付宝感觉开始扫描了一秒或者0.5秒这样才识别二维码,然后请求数据了。这种毫秒级别的扫描,在平时可能没有什么太大的影响,但是在每天早上骑车上班的时候,确实被我放大了很多倍。另外在高频次的日常扫描支付的时候,我想各位看官也是能够体会到这种差别的。不得不承认微信的扫描优化独步江湖。
    另外在使用单车的时候,其实我想问问为什么没有暂停功能。每次回家的时候会路过一些便利店或者是想要吃饭,但是如果把车放在外面不关闭,等我出来的时候车就被人骑走了。骑走了倒也无所谓,你倒是不骑了就给我关了啊。结果我在第二天早上,扫描时说我已经骑了八百多分钟,好像要十几块大洋,欲哭无泪。但是我在联系客服时,说明异常后没有扣款,这一点我是比较欣慰的。说到这个,想起了我一个哥们儿,也是类似的情况,但是骑的是mobike结果更是扣了几十块(心疼一秒钟)。其实单车可以更加人性化的,比如暂停功能,每天消费上限等等。
    总之,一个服务更厉害,一个产品更厉害。

    我的建议

    我有什么建议?当然他们可以认同我提出的bug,并认同我的解决方案啊。
    github源码

    取消用户点击事件跨平台操作方案

    由于有两位观众老爷的热烈讨论,给了我一点启发。
    无论是native还是hybrid在前一页面请求数据后跳转到下一页面,如果没有做优化,在网络不佳的情况下就容易出现本文的问题。
    1.如果是H5,可以利用定时器让函数延迟执行100ms,在100ms内如果还出发了函数可以删除上一次调用。最关键的就是这一点上了,js里面是可以取消函数调用的。
    2.ios端,解决方案有很多
    2.1在用户点击后500ms内不允许点击,当点击事件执行时恢复点击(外部控制)。
    2.2如本文设置bool值来阻止点击事件执行(外部控制)。
    2.3如果是写在block里面,而block是无法直接取消的,如果想要在内部取消可能需要建立检测(这一点我现在不知道如何下手,有大神指教木有),这样做比较麻烦。
    3.android端,解决方案类似。
    (注:最好是将这一功能抽出来,免得到处都是重复的代码。)

    相关文章

      网友评论

        本文标题:对支付宝产品细节的提一个小小建议

        本文链接:https://www.haomeiwen.com/subject/apmncxtx.html