JavaScript异步执行的坑

今天被JavaScript的异步执行坑了一把。

情况是这样的,我要接入云片网的短信接口。此平台为了防止自己的客户被短信轰炸机利用,要求客户在发送验证码之前必须要求验证码验证。于是我写了个先验证验证码然后才能点击“发送短信”按钮的程序。

ifenglv-loginpage

用户输入验证码之后,点击按钮,手机收到验证码。图片验证码的输入检测是这样的:一旦焦点离开input,就发送ajax到后台验证是否正确:

然后发现问题了:如果访客在输入验证码之后直接点击“发送按钮”。那么,焦点就直接从input离开,然后触发了按钮事件,并不会触发ajax去后台验证(正常的流程应该是点击空白区域失去焦点,验证通过,然后再点击按钮)。

于是我的做法是,按钮点击之后,先验证验证码一次,然后再触发发送短信

然而,结果依然是不会验证,仿佛验证验证码的代码没有执行。我在验证码的函数中打印出调试信息,却显示的确执行了。


最后发现,原来是因为“异步执行”。

在浏览器端,耗时很长的操作都应该异步执行,避免浏览器失去响应,最好的例子就是Ajax操作。在服务器端,”异步模式”甚至是唯一的模式,因为执行环境是单线程的,如果允许同步执行所有http请求,服务器性能会急剧下降,很快就会失去响应。

所以说,ajax的代码是异步执行的。在执行“验证码函数”的时候,点击按钮事件函数依然继续执行。到快执行完的时候,ajax这边也得到服务器的回复了,通过了验证。然而按钮事件却以“验证码未通过”执行完了函数。

现在我才知道这个“异步执行”是什么意思了。函数为了不阻塞,把剩下的事情教给callback函数来做,自己继续做剩下的事情。这个“同步执行”的编程很不一样,无法控制他们先做完这个、再做这个。但是无疑这提高了浏览器的响应能力。

参考:Javascript异步编程的4种方法


170113更新:最近又被坑到了,还是要怪自己不注意啊。

开发的过程中遇到一个bug,困扰了好久,有一个日历,需要根据issue显示日历中每一天的事件,现象是有的时候显示得出来,有时候显示不出来。仔细研究了一下,发现原来有两个地方有ajax调用,两个ajax收到结果之后都会更新同一个变量,其中一次更新是对的,一次是错的。如果错的比快的慢,那么后返回的错误的结果就会覆盖正确的……,改掉就好了。

 

 

Linus Torvalds谈代码品位:重写代码,排除特例

Linus接受了Ted演讲的采访:林纳斯•托瓦兹: Linux 操作系统之父, 采访中,主持人和他谈到代码品位的问题。展示了两段代码:

第一段,没有品位的代码:

code_no_teast

第二段,有品位的代码:

code_have_teast

这是从单向链表删除元素的函数,区别在于,第一段代码要判断“要删除的元素”是不是元素的头,而第二段并没没有做这个if判断。

原因是:如果要删除的是中间元素,那么只要把上一个元素的next指针指向下下一个元素就好了;如果要删除头元素的话,第一段代码所做的是,重新建一个头,指针指向下下个元素,然后把链表的头换成新的头;而第二段代码直接将原来的头的指针指向下下个元素了。

除了没有新开辟空间,第二段代码还好在:兼顾了所有情况,也就是不存在特殊情况的判断了。

Linus说:

这一个比较好。 它没有if语句。 这完全不影响—— 你不必了解这里为什么没有“if”语句, 你需要了解的是 有时候你可以换个角度看问题, 重写代码,排除特例, 完美覆盖所有情况。 这就是好的代码。 同时也很简单。 这是最基本的原则。 其实这都不重要—— 当然,细节非常重要。

对我来说,我愿意与之共事的人, 必须有好的品位,这就是如何…… 我举的这个例子很傻, 没什么意义,因为实在太短。 好的品位体现在更长的代码里。 好的品位体现在能看清全局 甚至有一种直觉, 知道怎么把事情做漂亮。

我在写代码时,喜欢写很多if。现在看来,这样不仅并没有提高安全性(自以为自己考虑了大多数情况),而且还变得更加繁琐。以后应该注意一下。


2018年1月2日更新:

在软件设计中,有一个原则叫做“最小惊讶原则”(Principle of Least Astonishment),可以参考这篇:http://lucumr.pocoo.org/2011/7/9/python-and-pola/ 和这篇 https://akaedu.github.io/book/ch03s03.html

 

django数据库migrate失败的解决方法

Django是一个MVC架构的web框架,其中,数据库就是“Module”。使用这种框架,我们不必写一条SQL语句,就可以完成对数据库的所有操作。在之前的Django版本中,我们像操作本地对象那样操作数据对象,在更改保存之后,执行python manage.py syncdb命令来同步数据库,在我使用的1.9.2版本中,需要依次执行一下步骤:

  1. python manage.py makemigrations (这个命令会根据你对数据库做出的更改生成操作数据库的python脚本)
  2. python manage.py migrate (这个命令会执行python脚本)

我遇到的问题是,执行makemigrations没有问题,但是执行migrate的时候有问题。于是我修改了modules.py中错误的代码,再次执行,却一直出问题。提示如下:

我删掉了makemigrations生成的代码,然后重新使用makemigrations生成脚本,还是出错。

原来,这是由于出错的时候,migrate命令已经执行了部分脚本,也就是说,to_user_id属性已经被操作过了,在数据库中,已经无需再操作了,所以执行migrate命令重新更新makemigrations的脚本会出错。

解决办法

重新生成makemigrations不行,执行migrate也只会全部执行。那么我们只好把数据库恢复到出错的那次执行前面的样子。

migrations

 

恢复方法:在project/app/migrations下有每次对数据操作所生成的脚本。找到出错那次脚本,打开脚本,可读性还是很高的,将所对应的数据库更改还原(当然得使用mysql语句了)。

然后删掉这次migration,重新make 然后执行。

实在不行,还有一个万不得已的办法。几乎所有的数据库错误都可以用这个方法解决:

将migrations文件夹下的文件除了__init__.py全部删掉,然后将数据库drop掉,重新建数据库。然后make,migrate,就可以使用一个新的数据库(但愿你永远用不到这个方法)。

 

在德国生活的感受

来德国一个月了,在这里生活的感触很多,让我觉得,我们国家在很多地方做的差太多了。总得来说,我觉得这是一个民主、友好、严谨的国家,但也只是目前的看法而已。我的历史老师说:当你在这里生活一段时间,回家之后,别人问你的印象,你说出来的只是对Reutlingen的印象,而不是德国。我大多数的时间都生活在Reutlingen,所以这篇博客可能有些狭隘。

25710667152_191b4fddad_k

德国的人民

这里的人非常友好。刚到这里,有点不习惯的是,在路上陌生人会主动跟你打招呼。拍照的时候,大家都会等你,没有一个人会从你的镜头前面走过去。超市的收银员也每次都会说Hallo。这里(Reutlingen)很多地方的十字路口没有红绿灯,但是会车的时候大家都特别谦让。路口有人,车总会等着人。一开始非常让人不习惯,你明明离路口比较远,他可以过去,但是却停下来等你。也许不习惯是个好事,万一习惯了车总是等人说不定回国会被撞死。我从没有听过有人按喇叭。

德国人的严谨是出了名的,我觉得名副其实。公交车站都会有时间表,而且几乎一点不差。在公交车上,大多数时间都很安静,很少有人说话。刚来的时候,去注册跑了几个办公室,一个比一个整洁。

25437927421_93de0e60b2_k

关于历史。德国挑起的一站和二战,而且有纳粹的黑历史。不过我觉得,他们有点矫正过了,谈起希特勒的时候,他们都很敏感。不认可希特勒对战后德国的贡献。一个朋友告诉我:“千万不要问一个德国人,‘你喜欢希特勒吗?’”。

德国的网络

这里的网速非常快,昨天更新Java的时候,64M只花了三四秒就更新完了。成人网站Pronhub,YouTube都可以毫无压力播放高清版本。当然,这和企业的配置也有关系。但是到国内的网速非常慢,我ssh到阿里云的服务器,特别难受,打个字甚至要1s才能看见。

很多人警告过我,千万不要在这里下载音乐和电影。德国对盗版的打击非常大,一首音乐可能面临700欧元左右的罚款。其实,德国人自己也对此耿耿于怀。有次在酒吧,他们(都因为下载音乐受到过罚款)吐槽这个说:你说你因为这个抓去坐牢,大家介绍自己。“我杀了人”,“我抢了钱”,你说“我下了首歌”,卧槽他们肯定吓死了——“这人敢下歌?”肯定让你当狱霸了。

关于监控。德国的网络自由在世界上好像排第四。我没有见过被屏蔽的网站。

德国的游戏

主机游戏的情况感觉和国内差不多,不过掌机不是很好。游戏商店老板说PSV nearly dead了。游戏品位上也偏好欧美类型,比如生化危机,dark souls之类的。LOL在这里也比较流行。总体来说,这里玩游戏的人(单机+网游)并没有国内的人多。

德国的游戏没有审查,有分级制度。但是有些游戏的敏感内容也是有删减的。比如在使命召唤6现代战争4大名鼎鼎的“不准说俄语”的关卡中,玩家是不允许射击平民的。我觉得也算是矫正过妄的一种表现吧。

norussian_feature


norussian2

德国的食物

非常难吃。这里有很多土耳其餐厅,有一种看起来像汉堡的东西比较流行。平时德国人花在做饭上面的时间非常少,他们竟然还震惊,中国人花很多时间来做饭,明明自己吃的东西和屎一样。如果你来过我们学校餐厅,你就知道上一句话不是在吐槽。在外面吃饭要付消费,而且菜单也不便宜。自己做要便宜很多。

WeChat_1458981872

垃圾分类

垃圾分为塑料、纸类、厨房垃圾、衣物、玻璃、其他垃圾。其中玻璃还分颜色。而且非常普及,我们村很小的地方,都是三个或四个垃圾桶。朋友告诉我,在日本和新西兰更厉害,茶包都要分是什么材料做的。分不好就罚款。

25831542695_80fe12c90c_z

这样很麻烦,因为你不可能在房间里放四个垃圾桶,但是好处也显而易见。这里有非常非常多的车,但是,下图是这里的天空。

25440156724_48774c8896_k

市中心的一条河。

25952393342_2dd8c842c8_k

政治

德国是有很多民族组成联邦制国家。我的感受是,自治意识很高。州有自己的旗帜,很多活动都会看见自己地方的标志。我们学校很多人穿着印有校旗的衣服,学生组织都会有印有标志的袋子、笔、本子。

这个月经历了州政府的选举,遇到过一次游行。

25805603936_d0fe3412ce_k

人们可以选出自己支持的党派。

还有一些习俗,比如吃饭之前德国人会说:祝你好胃口。打喷嚏了别人会说“Bless you”(好像欧美都这样)。很有意思。

Again,这可能只是Reutlingen。可能这就是旅行的意义吧,多去一些地方,才不让自己的看法局限在这样一个小村子里。言语就像风,很多事情只有自己见的才是真的。有人说,往北往西,那里的德国人不像这里这么友好;也有人说,那里的城市更大,人们更加开放。就像我来德国人之前,有人说德国人很排外,因为中国人抢走了他们的工作机会。但是很多人告诉我,德国人憎恨的是从土耳其和其他国家来的人,白白领社会福利,而不做出贡献。像中国来的程序员,他们是欢迎的。

25810684581_186cef36c4_k

 

盗版之危害

最近”引力波“这个名词流行起来之后,出了一个民科“诺贝尔哥”。现在几乎可以确定的是,郭英森做的不是真正的科学,而很可能只是知道哗众取宠的名词。很多年来,中国的社会一直很容被民科诱导,再加上无良媒体总想搞大新闻,夸大事实煽风点火,很容易出现某种反智主义。我几乎已经习以为常了,对很多媒体也是一笑置之。但是惊讶的是,我看到了姚晨这样一条微博:

yweibo-of-yaochen-praicy

我觉得一个与自己领域不相关的、受人关注的明星转发这样一条信息,动机很值得怀疑。当然,肯定不是从中的到了广告费,这不太现实。我觉得是明星是因为需要保持一种“受关注度”。

一直以来,我们对公众人物的期望太多了。比如出现灾难事故,我们期望他们捐款,觉得没有别人多,去微博骂,不捐,更要骂,给国外捐,还要骂。国庆,你要表示爱过,不然,骂你。出现这样一种情况,可能和明星们来钱的方式有关,靠着出歌卖CD赚钱实在太少了,更多的收入要依靠粉丝的支持和出场费用。一旦受到封杀和抵制,打击巨大。

正式因为正版产品卖不出去,才造成了这样一种不健康的状态。这种危害也可以见于别的行业,例如游戏。

对于单机游戏来说,良心开发一款游戏,需要巨大的开发时间和成本。回本就靠发售的时候出售正版。然而国内正版风气实在太差,导致基本不可能赚钱。所以国内发展的基本上是手游,网游,依靠在线道具出售盈利,然而很难见到里程碑式的作品。

还有电影。现在的时代,即使不去电影院,在线买个会员或者一次性为电影支付在线费用,也就几块钱,这也会支持导演和演员们,但是人们更倾向于用种子来下载。

盗版如此猖獗,错不全在群众,很大意义上,这是政府的过失。一方面,我们对盗版的打击力度太小,导致使用盗版的成本和风险都太小了。我们随处可以下载到音乐、电影和游戏,当然不会有人付费。我之前买过一台二手的PS3,本想买几盘游戏补补课,但是到手之后,发现这是一台破解机。一盘游戏上百,禁不住诱惑就去玩盗版了。后来想从正的时候发现被索尼ban了,损失惨重。这也给了我一个教训,以后再也不碰盗版游戏!现在很多游戏厂商不愿意开发PC版本的游戏,甚至不愿意移植,就是因为PC平台的盗版严重。而PSN平台对正版保护力度很大,就有很多经典的作品。

101087684

另一方面,我们对正版的支持力度太小。众所周知,我们国家有着非常严格模糊的审查制度。这其中有很多不好说的因由。这就造成什么能在大陆上,什么不能,有着很模糊的定义,法律上完全是空白,一切广电说了算。像欧洲和美国都有一套电影和游戏的分级系统,对于血腥、色情和暴力明文划分。而在中国,有很多优秀的作品因为文化部一纸禁令不能发行。即使要封杀什么东西,请明文规定,指出其违反了什么法律,我们无法可说,可是稀里糊涂遭到封杀,让人接受不了。更糟的是,前几年国内出现一款游戏,尺度很大,因为没有分级系统,很多低领人群可以轻松玩到,其画面非常色情、血腥,让人担心。这些作品的封杀,导致我们想要像国外的玩家、观众一样得到他们,只能使用盗版。

打击盗版,支持正版不能是一句空话,很大程度上,取决于国家的态度。希望早日能有法可依,执法必严。不要等到没有人再去够买正版,没有人再去写歌,不要大众对明星暴力的期待持续下去,不要让我们的人民不能从正当的劳动中得到一分钱,反而靠着偷鸡摸狗(是我就是在说破解网站,操你妈的)之事才能获利,不要等到人们丧失了创造的热情和信心的那一天,不要等他们不能再创作的时候说“我们欠谁谁一张电影票”,现在就用行动支持他们。