【ArchSummit】如何通过AIOps推动可量化的业务价值增长和效率提升?>>> 了解详情
写点什么

关于响应式编程你可能错过的信息

  • 2014-07-04
  • 本文字数:1706 字

    阅读完需:约 6 分钟

在函数式编程重新焕发生命力的当下,结合了函数式编程思想的函数式响应型编程(Functional Reactive Programming,简称 FRP)在 GUI 编程等领域又吹来一阵清风。虽然 FRP 的理论与实践可以追溯到上个世纪九十年代,但它蕴含的诸多概念对于大多数程序员而言,还是全新的知识。维基百科对FRP 的定义为:

函数式响应型编程是使用函数式编程构建块针对响应式编程的一种编程范式。它主要用于GUI 编程、机器人技术、音乐流处理等领域,通过显式地对时间进行建模来简化问题域。

这样的定义未免太过于宽泛了。 Stackoverflow 对此的回答倒是详尽而细致地阐述了 FRP 的今世前身,可惜又失之艰深,若用于学术讨论,确乎是最佳选择。例如,我们可以阅读发表于 1997 年由 Conal Elliott 与 Paul Hudak 撰写的论文《 Functional Reactive Animation 》,以及同样由 Conal Elliot 于 1998 年发表的论文《 Composing Reactive Animations 》。

FRP 最早发源于 Haskell 社区。Haskell 官方网站专门介绍了FRP 的知识。这篇介绍还提供了诸多讲解FRP 的资源,同时提到了一些实现了FRP 的库,例如 Sodium Grapefruit Reactive Yampa 等。当然,这种来源于函数式编程的编程范式,自然也可以运用于除 Haskell 之外的其他具备函数式编程特性的语言,例如 JavaScript,Scala,F#等。因此,若要理解什么是 FRP,最佳方式莫过于通过一个完整的案例来理解。

近日,Andre Staltz 在 Github 上发布了一篇长文《关于响应式编程你可能错过的信息》,通过运用JavaScript 和RxJS,以FRP 的编程范式实现了如Twitter 中推荐朋友的功能。这篇文章围绕着FRP 的一个核心概念“FRP 是针对异步数据流进行编程”进行讲解,并抓住了FRP 的本质,即将任何事物都视为一个流对象,包括变量、用户输入、属性、缓存、数据结构等。这种针对流的处理方式有些像管道- 过滤器模式,而它又与函数式语言的组合子Combinator 是相呼应的。例如我们可以对流进行map、filter 等组合操作。而FRP 对事件的订阅,则符合观察者模式的设计思想。文中给出了一个FRP 例子,它用JavaScript 处理了“双击”的事件流:

复制代码
// The 4 lines of code that make the multi-click logic
var multiClickStream = clickStream
.buffer(function() { return clickStream.throttle(250); })
.map(function(list) { return list.length; })
.filter(function(x) { return x >= 2; });
// Same as above, but detects single clicks
var singleClickStream = clickStream
.buffer(function() { return clickStream.throttle(250); })
.map(function(list) { return list.length; })
.filter(function(x) { return x === 1; });
// Listen to both streams and render the text label accordingly
singleClickStream.subscribe(function (event) {
document.querySelector('h2').textContent = 'click';
});
multiClickStream.subscribe(function (numclicks) {
document.querySelector('h2').textContent = ''+numclicks+'x click';
});
Rx.Observable.merge(singleClickStream, multiClickStream)
.throttle(1000)
.subscribe(function (suggestion) {
document.querySelector('h2').textContent = '';
});

文中对例子的阐述,一个很有启发的内容是如何采用 FRP 的思想对需求进行分析。例如针对需求“通过 API 加载账号数据,并显示 3 个推荐”,即可以分解为:

  • doing a request
  • getting a response
  • rendering the response

这种将一切视为“流”,然后针对各个阶段进行数据转换的方式,非常符合函数式思想,也极好地阐述了 FRP 的基本要义。

若要了解 FRP 的详细知识,可以深入阅读 Andre Staltz 的这篇文章。此外,InfoQ 中国在去年也曾发表过由网易的邓际锋撰写的关于FRP 的文章《函数式反应型编程(FRP) —— 实时互动应用开发的新思路》。这篇文章很好地通过实现一个类似Flicker 的小应用阐述了FRP 的概念。


感谢杨赛对本文的审校。

给InfoQ 中文站投稿或者参与内容翻译工作,请邮件至 editors@cn.infoq.com 。也欢迎大家通过新浪微博( @InfoQ )或者腾讯微博( @InfoQ )关注我们,并与我们的编辑和其他读者朋友交流。

2014-07-04 00:403401
用户头像

发布了 109 篇内容, 共 39.8 次阅读, 收获喜欢 13 次。

关注

评论

发布
暂无评论
发现更多内容

【LeetCode】重复的DNA序列Java题解

Albert

算法 LeetCode 6月日更

架构师实战营 模块六总结

代廉洁

SpringCloud Gateway 路由转发性能优化

黄仲辉

性能优化 动态路由 SpringCloud Gateway JMH性能基准测试

Single-Spa构建第一个微前端项目

devpoint

Vue 大前端 6月日更

【21-5】Grafana 时间Panel 如何使用

耳东@Erdong

Grafana 6月日更 panel clock

网络攻防学习笔记 Day43

穿过生命散发芬芳

网络攻防 6月日更

HTTP 长连接和短连接

看山

TCP/IP HTTP协议 6月日更

架构实战营-作业六

大可

【Flutter 专题】105 图解自定义 ACEPageMenu 滑动菜单 (一)

阿策小和尚

Flutter 小菜 0 基础学习 Flutter Android 小菜鸟 6月日更

未来,能源枯竭可以逆转吗?

脑极体

【LeetCode】第一个错误的版本Java题解

Albert

算法 LeetCode 6月日更

内卷的出路是躺平?

Qien Z.

创新 内卷 6月日更 躺平

SpringCloud Gateway 路由数量对性能的影响研究

黄仲辉

性能优化 动态路由 SpringCloud Gateway JMH性能基准测试

【通俗易懂】虚拟DOM,如何更高效DIFF

蛋先生DX

Diff 6月日更

话题讨论|如何看待腾讯试点强制6点下班

石云升

话题讨论 加班文化 6月日更

立flag(第………………次)

凯迪

随笔杂谈

一文带你深入了解 Java 字节码

mghio

技术 后端 Java 25 周年 基础

未来,能源枯竭可以逆转吗?

白洞计划

TempDB 的使用和性能问题

悟空聊架构

sql 性能调优 6月日更 TempDB

Java语言概述以及环境搭建

若尘

java编程 6月日更

贪心算法最优装载问题(Java代码实现)

若尘

数据结构 贪心算法 6月日更

redis分布式锁原理

Skysper

redis 分布式锁

并发王者课-黄金2:行稳致远-如何让你的线程免于死锁

MetaThoughts

Java 多线程 并发

Python——数值列表

在即

6月日更

Scrum Patterns : MetaScrum(译)

Bruce Talk

敏捷开发 译文 Agile Scrum Patterns

架构师实战营 模块六作业(拆分电商系统为微服务)

代廉洁

架构实战营

Windows 10 如何设置网络属性为私有

HoneyMoose

【Vue2.x 源码学习】第十二篇 - 生成 ast 语法树-流程说明

Brave

源码 vue2 6月日更

策略模式怎么玩?

卢卡多多

设计模式 策略模式 6月日更

模块六作业 - 拆分电商系统为微服务

张大彪

JAVA设计模式系列--单例模式

加百利

Java 后端 设计模式 单例模式 6月日更

关于响应式编程你可能错过的信息_语言 & 开发_张逸_InfoQ精选文章