博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
初探 BaconJS
阅读量:6882 次
发布时间:2019-06-27

本文共 4027 字,大约阅读时间需要 13 分钟。

,期待你的 Star 。

一、BaconJS 是什么

BaconJS 是一个函数响应式编程(Functional Reactive Programming)的 JS 库。虽说是函数响应式编程,但我用了会儿,感觉响应式编程更令人印象深刻,它与业界比较火的响应式编程库 RxJS 有点类似。值得一提的是,Angular 内置的许多 API 就使用了 RxJS 。可见,响应式编程可能会是未来一个很重要的发展方向。

二、如何理解 FRP

函数响应式编程(Function Reactive Programmin),简称 FRP 。这是 BaconJS 最显著的特点,要想入门 BaconJS ,只需理解这种编程思维即可,不必被官网提供的海量 API 所困扰。

FRP = FP(Function Programming) + RP(Reactive Programming)

顾名思义,函数响应式编程 = 函数式编程(Functional Programming) + 响应式编程(Reactive Programming)

这两种编程模式是两个很大的话题,都可以聊很久。我在这里就大致的罗列下两者的一些特点,并简述下我个人的理解。

2.1 函数式编程(FP)

函数式编程是业界很火的一个概念,我曾不止一次试图去彻底的弄懂它,但至今也是一知半解的状态~

不管怎么样, 以下几个 FP 的特点还是需要了解的:

  • 纯函数(Pure function),函数唯一的输入只会有唯一的输出。
  • 不可修改状态(Immutable state)。

我们常常把 FP 和命令式编程(Imperative programming)进行比较,我个人认为 FP 更加强调代码的可预测性(Predictable),尽可能的避免代码的副作用(Side effect),更加关心数据的映射,而命令式编程关心的是解决问题的步骤

2.2 响应式编程(RP)

随着 Google 前端框架 Angular(Angular 1.x 称为 AngularJS,Angular v2+ 称为 Angular) 的发布,由于 Angular 几乎所有的异步接口都使用了响应式编程库 RxJS ,响应式编程得到了越来越多的关注。

我算是半个 NG 粉,有用 Angular 开发过一个项目,用下来感觉 RxJS 的开发体验特别好。总的来说,RP 有如下几个特点:

  • 流(Stream)的概念,衍生的概念有:数据流(Data stream)、事件流(Event stream) 。
  • 链式调用(Chain invoke),使代码看起来清晰、简洁。
  • 处理异步数据流的神器。

响应式编程主要是用来处理异步数据流(Asynchronous data stream),可以是 ajax 请求产生的数据流,也可以是 DOM 事件(或者其他时间)产生的事件流。

对于其核心的概念:流(Stream),我的理解是:流是按照时间顺序排列的一系列正在进行的事件。在这个概念的基础上,RP 框架提供了一系列(海量)的接口来处理流,使得我们开发出来的代码显得非常清晰。

想要深入的理解响应式编程,推荐阅读:

三、基本概念

3.1 Observable

观察对象,是 EventStream 和 Property 对象共同的父类,大部分对流进行操作的接口都封装在该对象中。

3.2 EventStream

EventStream,又称事件流,是 BaconJS 中出现频率最高的一个词。其本质就是一个流对象,开发者可以通过链式的方式进行调用,并且可以通过一些 Stream API 来提高开发的效率。

3.3 Property

Property,可以理解为事件流对应的"值",通过 toProperty( ) 接口可以将事件流转化成 Property 对象。

3.4 举个例子

为了方便理解 EventStream 和 Property ,我们来看个具体的例子。

需求:某个表单页面,需要在上面填写手机号和验证码才可以点击注册按钮。

剖析下这个需求,我们需要做下面几件事:

  • 需要显示手机号和验证码的输入框,另外还有一个注册按钮。
  • 验证输入手机号和验证码格式的有效性。
  • 如果手机号和验证码都填写了,且都是有效的,将注册按钮的 disabled 属性设置为 false 。

核心代码如下:

function isPhoneAvailable(n) {    return /^[1][3,4,5,7,8][0-9]{9}$/.test(n);}function isVCAvailable(c) {    return c.length === 4;}// 1. 生成手机号码输入框对应的 'keyup' 事件流。// 2. 通过 map 方法校验手机号码的有效性。// 3. 将事件流对象转化成 Property 对象,方便后面使用 'and' 方法。let phoneNumber$ = $('#phone_number')    .asEventStream('keyup')    .map((event) => {        let value = $(event.target).val();        return isPhoneAvailable(value);    })    .toProperty('');// 同上let verificationCode$ = $('#verification_code')    .asEventStream('keyup')    .map((event) => {        let value = $(event.target).val();        return isVCAvailable(value);    })    .toProperty('');// 通过 'Property' 对象的 'and' 方法,生成一个新的 'Property' 对象// Property.prototype.and 的含义:等同于 return A&B;let registerButton$ = phoneNumber$.and(verificationCode$);// 对 registerButton$ 取反,然后通过 'assign' 方法设置注册按钮的 disabled 属性registerButton$.not().assign($('#register_button'), 'attr', 'disabled');复制代码

四、常用的 API

4.1 Bacon.fromEvent( )

用途:通过 DOM 的 EventTarget 或是 NodeJS 的 EventEmitter 来创建事件流。

NodeJS 例子:

const Bacon = require('baconjs').Bacon;const events = require('events');const eventEmitter = new events.EventEmitter();Bacon    .fromEvent(eventEmitter, 'someEvent')    .onValue((data) => { console.log(data) });eventEmitter.emit('someEvent', 'some data');// 输出 =>// 'some data'复制代码

4.2 Obervable.property.map( )

用途:映射到一个新的值。

例子:

// 例子一: 可以给回调函数传参Bacon    .fromArray([1, 2, 3])    .map(function (a, b) {        console.log(`${a}, ${b}`)        return a*b;    }, 3)    .log(); // 输出 =>// 3, 1// 3// 3, 2// 6// 3, 3// 9// 
// 例子二: 可以用 '.foo' 获取对象的某个属性值Bacon .fromPoll(1000) .map(() => { return { foo: `foo${
parseInt(Math.random()*100)}` } }) .take(4) .map('.foo') .log();// 输出(foo后面的数字是随机的) =>// foo25// foo35// foo98// foo76//
复制代码

4.3 EventStream.merge( )

用途:将一个 EventStream merge 到另一个 EventStream 中。

例子:

let eventStream1 = Bacon.fromArray([1, 2, 5]);let eventSream2 = Bacon.fromArray([3, 4]);eventStream1.merge(eventSream2).log(); // 输出 =>// 1// 2// 3// 4// 5// 
复制代码

4.4 TIP

刚开始使用 RxJS 的时候容易被海量的 API 给吓到了,而且并不是所有的接口都有 Demo 有些接口会显然比较难理解。BaconJS 也是一样,有许多的接口,光看官方的文档有时会比较难理解。

这里,我们分享一个我快速理解某个接口的 TIP 。那就是:查阅具体接口单元测试(UT)中的所有 Case 。个人感觉,这比看官方文档高效很多。

转载地址:http://pribl.baihongyu.com/

你可能感兴趣的文章
jdk的安装与配置
查看>>
Python数据抓取技术与实战 pdf
查看>>
20145209 《信息安全系统设计基础》第3周学习总结
查看>>
python 进程
查看>>
Grunt插件uglify
查看>>
export 与 export default
查看>>
linux配置网卡
查看>>
正则表达式语法
查看>>
013、Dockerfile构建镜像(2019-01-02 周三)
查看>>
c# mvc如何获取xml文件
查看>>
mongodb Java(八)
查看>>
JavaScript随机数
查看>>
ASP.NET验证控件——RequiredFieldValidator
查看>>
strstr
查看>>
MySQL 条件 select case 的实现(解决 零 做分母的问题 )
查看>>
openNebula rgister img instance vms error collections
查看>>
error Infos
查看>>
PL/sql配置相关
查看>>
接着浅析table-cell的简单应用
查看>>
Project 10:简单图像的绘制
查看>>