写点什么

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

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

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

关注

评论

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

linux下七种文件类型

xiezhr

Linux linux操作 linux运维 linux 文件权限控制

面试现场:遇到不会回答的问题,如何力挽狂澜 ?

xcbeyond

面试 3月日更

思考需要大声,写下便是永恒——未完待续

Justin

总结 28天写作

2020年张小龙非公开课的一点思考

lenka

3月日更

TCP 三次握手与四次挥手

insight

TCP 3月日更

有利可图的NFT,NA公链(Nirvana Chain)NAC公链怎么面对高额Gas费的?

区块链第一资讯

区块链 公链 挖矿

Python 分通道读取图像数据,取经之路第 4 天

梦想橡皮擦

28天写作 3月日更

你真的懂Spring解决循环依赖吗?

Java 架构 Spring Boot

(28DW-S8-Day28) 战略流程重整

mtfelix

28天写作

我们为什么需要云原生?

脑极体

翻译:《实用的Python编程》07_00_Overview

codists

Python

多队列网卡简介

依旧廖凯

28天写作 3月日更

《Redis 核心技术与实战》学习笔记 04

escray

redis 学习 28天写作 3月日更 Redis 核心技术与实战

我是如何拿到5大银行offer

小舰

面试 银行 笔试 校园招聘

Go语言学习笔记:数组

worry

数组 Go 语言

C/C++Linux服务器开发完整学习路线(含免费学习资料下载地址)

Linux服务器开发

Linux 后端 C/C++ Linux服务器开发 Linux后台开发

你是否觉得上级的能力不如你?

石云升

心理学 28天写作 职场经验 管理经验 3月日更

源码分析-Netty: 架构剖析

程序员架构进阶

架构 Netty 源码剖析 28天写作 3月日更

永动金融EGG公链去中心化社交平台与通证EFTalk全球正式亮相

币圈那点事

区块链

Wireshark数据包分析学习笔记Day16

穿过生命散发芬芳

Wireshark 数据包分析 3月日更

我从外包辞职了,10000小时后,走进字节跳动拿了offer

Java 编程 程序员 架构 面试

并发编程:一次搞定单例模式

Java架构师迁哥

28天

ES_her0

28天写作 3月日更

Python 随机字符串

HoneyMoose

Python 随机数函数 choices

HoneyMoose

老板要我开发一个简单的工作流引擎

Java小咖秀

架构 工作流 开发 工作流调度 工作流引擎

大专生阿里/腾讯/京东面经分享:Java面试精选题+架构实战笔记(技术狂补)

比伯

Java 编程 架构 面试 计算机

Hadoop UI 系统 -HUE 详细剖析

大数据技术指南

大数据 hadoop 28天写作 3月日更

最近的一点思考「Day 28」

道伟

28天写作

翻译:《实用的Python编程》07_01_Variable_arguments

codists

Python

国内可用镜像站整理

弘毅

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