阅读 491

扬帆起航:从命令式编程到函数响应式编程

前言:在大学时期,我用Ionic写过一个查看校园信息的app,利用投放广告盈利的方式,我赚到了一台MacBook Pro。在之后的日子里,无论是工作,学习还是生活,它都给我带来极大的便捷。我至今仍心存感激。所以我对Ionic的核心框架Angular充满好感。即使现在的工作中用react居多,但是闲暇时还是会追一追Angular的文档,写一写笔记。 随着工作经验愈发丰富,Angular越来越演变成一种信仰。我在业务编码过程中遇到的诸多问题在Angular中均有优雅的解决方案,这点足令我震撼。所以我决定将它分为不同的章节,依次研读。 我首先选择了Rx,因为它不仅是Angular的核心之一,而且我觉得学习完之后可以应用到现在的工作中,两者兼得。幸运的是,我在西湖边发现了修炼的宝地:平湖秋月。看着荡漾的水波,想象自己是一段流,似乎就化身为Observable,与Rx心灵相通。这极大的提高了我修炼的速度。下面的章节我会将自己学到的知识记录下来,与各位分享。

平湖秋月边修炼Rx

首先,我认为前端开发做好2件事情就够了:**1.渲染界面,2.根据用户输入渲染界面。**其中渲染界面可以利用React之类的库来完成,它们提供了一种从state映射到view的方式,你只需要管理好state即可,渲染view的工作丢给它们去完成。而根据用户输入渲染界面这部分会比较复杂,其中涉及到异步处理,业务逻辑代码编写等等。项目变得有一定规模之后,会变得比较难以维护。一个很重要的原因在于没有一个直观的组织代码的方式,让维护者一眼看上去就知道这段代码想要表达什么。

接下来,要想解决这个问题,需要好好审视一下web开发的本质。用户点击鼠标,触发了一个事件,你的程序接收到之后开始做一些处理。用户移动鼠标,触发了一个事件,你的程序接收到之后开始做一些处理。只要稍微一想,就会明白web开发其实就是和一系列的事件打交道,只要将这些事件以清晰的方式处理好了,我们的代码自然会变得清晰起来。自然的,**我们会想到观察者模式。**我们的处理程序都是用户事件的接收者,订阅了用户的事件源,等到有事件源发出通知时,我们的程序就会做出响应。本着顺势而为的哲学思想,我们应该用响应式的思想来编写代码。

然后思考一个问题:我们编写的代码的本质是什么呢?**是一系列的处理函数。**既然是函数的话,我们可以对计算机说:我想要这样,然后想要那样,最终我想得到的结果是这样。而不是具体的告诉计算机你应该先这样,在那样,最后在这样。前者是函数式的思维,后者是命令式的思维。有点绕,举一个直观的例子吧:最近面试了一个实习生,让他写一个数组去重的代码,他的实现如下:

实习生的数组去重代码

他的思想就是告诉计算机你应该先把这个数组遍历一遍,然后把数组的值当做map的键赋值给map,并初始化为1。然后遍历这个map,取出它的键,push到数组中。返回这个数组。是不是感觉很麻烦。这就是命令式的思维。其实这个实现中有许多bug,比如给定数组arr要是有数字的话,转换后的数组会把数字变成字符串。for in也会遍历原型链上的值。想一想都觉得可怕。要是用函数式的思维呢?

函数式数组去重

是不是清爽许多。这段代码的本质是告诉计算机:**我想要把这个数组中除了第一个的相同的数过滤出去。**简洁明了,直接告诉计算机你想要什么就好。**组合一些现有的函数来进行语义化编程。只要一眼看上去就知道这段代码想要表达什么。**在监听到用户的事件时,只需要执行一系列函数,把处理后的结果给负责渲染view的库就OK了。

那为什么函数式编程最近才变得火热起来呢?这是一个历史原因。当时阿兰图灵和冯诺依曼祖师爷创立了计算机这门学科时,因为是开天辟地的创造。所以最早一批学者都有着其他专业背景,但主要分为2大派:电子电气和数学。它们带来了不同的观点。数学家提出的编程语言模型自然具有数学气质,优雅且易于管理,其中Lambda演算就是用纯函数的组合来描述计算过程,如果一个问题能够用一套函数组合的算法来描述,那么就说明这个问题是可计算的。但是当时硬件制造技术很不发达,电子元件制造成本又高,体积又大,无法在一个小芯片上放置多个元件。既然这样,那只好省着点用了,命令式编程就这样兴起了。看过《乔布斯传》的朋友们应该知道,当时乔布斯和沃森为了一款游戏减少几个芯片的使用而耗费精力。

随着硬件技术的进步,这些都不是问题了。所以数学家们提出的优雅的解决方案慢慢的变得流行起来。

最后,我们得到了一个结论。web开发中根据用户输入处理这一步的解决方案即为函数式编程+响应式编程。而这两者结合起来即为**函数响应式编程。**这正是Rx.js的思想。优雅迷人。接下来让我们一起揭开她美丽的面纱吧n(≧▽≦)n。


后记:如果想认识一群有趣的人,经历一些有趣的事情的话,那么来酷家乐加入我们前端团队吧。简历可以发我邮箱:chonger@qunhemail.com,我来帮你内推。另外秀一波我的无敌景观工位:

无敌景观工位