我在JavaScript中踩过的坑

我在Javascript中踩过的坑!

前言

时至今日也没有系统深入的学习过JavaScript,虽然常用,但是也只停留在最基础的使用上。没有系统深入的了解,必然要踩一些前端众所周知,却让小白绞尽脑汁地大坑!

今天又在坑里摸了一天,记录一下,权当是写日记了。

最近连续加班,确实有些身心俱疲;加上昨天下午的“午后小睡”导致晚上失眠,到快四点钟才睡着,今天早上快十点钟还躺在床上。

需求

正在逛Twitter,做毕设地学妹给我提了两个需求:

  • 登陆页面的表单检验;
  • 注册页面的重复用户名检测。

问题:从Ajax中返回值

用JQuery.validate插件给登陆表单加了校验,挺简单,同样的方法给注册界面加个校验,唯一不同的是需要使用ajax从后台请求到用户名是否已经存在,也挺简单。

于是乎,有了下面这段代码:

// do something
$.validator.addMethod("checkUniqueUsername", function(value, element, params) {
    return this.optional(element) || checkUniqueUsername(value);
}, "用户名已被占用!");

function checkUniqueUsername(username) {
    if (username !== null && username !== undefined && username !== '') {
        var data = {'loginname': username};
        $.ajax({
            type: 'post',
            url: '/checkloginname',
            data: JSON.stringify(data),
            dataType: 'json',
            contentType: 'application/json',
            success: function (res) {
                return (parseInt(res.tip) === 0);
            }
        });
    } else {
        return false;
    }
}

三五分钟,就写完了代码,跑一跑测一下准备验收了。诡异的事情出现了,checkUniqueUsername()总是返回false。

Ajax中return的结果

没事,静下心来慢慢调,就这几行代码,怎么说也要给你调得明明白白的。调试后发现parseInt(res.tip)===0是true,可是return 之后函数的返回值是false,这没道理啊!

网上查了一下,原来是在ajax中直接return并不是return到外层函数中,不深究,改个写法,于是有了v2版本:

// do something
$.validator.addMethod("checkUniqueUsername", function(value, element, params) {
    return this.optional(element) || checkUniqueUsername(value);
}, "用户名已被占用!");

function checkUniqueUsername(username) {
    if (username !== null && username !== undefined && username !== '') {
        var result = false;
        var data = {'loginname': username};
        $.ajax({
            type: 'post',
            url: '/checkloginname',
            data: JSON.stringify(data),
            dataType: 'json',
            contentType: 'application/json',
            success: function (res) {
                result = (parseInt(res.tip) === 0);
            }
        });
        return result;
    } else {
        return false;
    }
}

检查了一下,再也想不出还能有什么问题了,那就跑一下吧。诡异的结果又出现了,函数返回值依旧是false,心态崩了,这就好比 var count = 1; console.log(count);却输出了2一样,难以置信!

Ajax同步和异步

查了半天,终于看到一个答案:ajax的同步和异步。可谓是一语惊醒梦中人,我责备自己为什么调试了这么久,却没有想到这个方向,而且同步异步的坑已经不是第一次踩了。v3版本终于解决了这个问题,失之毫厘,差之千里。

// do something
$.validator.addMethod("checkUniqueUsername", function(value, element, params) {
    return this.optional(element) || checkUniqueUsername(value);
}, "用户名已被占用!");

function checkUniqueUsername(username) {
    if (username !== null && username !== undefined && username !== '') {
        var result = false;
        var data = {'loginname': username};
        $.ajax({
            type: 'post',
            url: '/checkloginname',
            data: JSON.stringify(data),
            dataType: 'json',
            contentType: 'application/json',
            async: false,
            success: function (res) {
                result = (parseInt(res.tip) === 0);
            }
        });
        return result;
    } else {
        return false;
    }
}

但是每次运行控制台都会出现JQuery的提示:使用同步会降低用户体验,总归是有个解决办法,有时间再深究一下吧。

JavaScript浮点运算

今天的经历让我回想起了去年遇到的一个JavaScript的问题,当时在做一个现金流管理系统,遇到一个需求是根据固定利息和浮动利息自动计算出最终利息,随便输了几组数据测试,没有出现异样,但是最后一组数据的时候出现了诡异的结果!4.1 + 4.3 = 8.399999999999999,这真是见了鬼了。。很久之前学过的知识这分钟哪里回想得起来。上网查了才发现原来是JavaScript的设计缺陷导致的问题,也都提出了几种解决方案。

后话

平时用Java习惯了,思维方式有些不灵活,从对Python的理解中也能看出来。

总之,遇到问题,要发散思维,尽量快速的去确定调查的方向,最终尽快的解决问题。