写点什么

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

  • 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:403485
用户头像

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

关注

评论

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

测试右移与自动化测试

刘冉

自动化测试 测试右测

【Flutter 专题】08 图解页面小跳转 (一)

阿策小和尚

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

如何在 JavaScript 中操作二维数组

devpoint

JavaScript array 数组操作 11月日更

CSS布局之display:flex

Augus

CSS 11月日更

[ CloudWeGo 微服务实践 - 08 ] Nacos 服务发现扩展 (1)

baiyutang

golang 微服务 11月日更

openLooKeng v1.4.1 上线,OmniData Connector 来了

openLooKeng

大数据 openLooKeng

2021 年 Node.js 的发展趋势

CRMEB

架构实战模块作业八

Yina🌝很浪🌊

架构实战课

大数据训练营学习总结

arctec

模块三

毫米波 5G 比公共 Wifi 快近 30 倍,但覆盖范围相似

吴脑的键客

网络

模块三作业-外包学生管理系统

二手攻城师

「架构实战营」

用vscode创建第一个flutter项目

坚果

flutter 11月日更

DevOps为何在中国发展滞后?

SoFlu软件机器人

MySQL打印死锁日志

Simon

MySQL 死锁

题目二:架构设计题

arctec

题目三、简述HDFS的读写流程

arctec

微信小程序开发:使用字体图标的方法

三掌柜

11月日更

创业自研技术团队筹建需要注意什么?

boshi

创业 团队管理

敏捷开发专家一席谈:云原生技术下的华为云DevOps实践之路

华为云开发者联盟

DevOps 敏捷开发 华为云 devcloud

体验内容更新,MindSpore轻松掌握

Geek_6cdeb6

架构训练营 - 模块三作业

VegetableBird

架构训练营 架构实战营

技术架构+应用场景揭秘,为什么高斯Redis比开源香?

华为云开发者联盟

数据库 redis 开源 云原生 高斯Redis

设计消息队列存储消息数据的MySQL表格

毛先生

极客时间架构实战营作业八

jjn0703

架构实战营

模块三作业 外包学生管理系统详细架构设计

小朱

架构实战营

Go语言,测试功能详解-上

微客鸟窝

Go 语言 11月日更

如何“拼”出一个页面-游戏中心模块化实践

vivo互联网技术

开发 组件化 产品方法论

Flink CDC 2.0 数据处理流程全面解析

大数据技术指南

11月日更

懒人畅听网,有声小说类目数据采集,多线程速采案例,Python爬虫120例之23例

梦想橡皮擦

11月日更

详细剖析Kafka架构及组件

五分钟学大数据

11月日更

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