函数式反应式编程(FRP)是一种新兴的编程范例,最近在网络世界中越来越流行。 这种受欢迎程度不仅与视频流媒体巨头Netflix在博客中写道如何应用FRP来优化其API有关 ,还因为它实际上提供了一种优雅的方式来降低处理时变事件和异步操作的复杂性。
一个例子
让我们看一个示例,看看FRP如何解决以前可能需要用JavaScript处理的问题-当对服务器的异步请求没有按请求的顺序返回时。 为了演示起见,假设我们需要一个级联的下拉列表,该列表包含2个相关的下拉列表。 当您从第一个下拉列表中选择一个值时,将发出AJAX请求以获取值列表以填充第二个下拉列表。 您可以在jQuery(或任何其他JavaScript框架)中实现以下内容:
<script>// <![CDATA[
$('#dropdown1')change(function () {
var selected = $(this).val();
var promise = $.ajax('/path/to/your/server', {
data: {value: selected}
});
promise.then(function(data){
var html = $.map(data, function(item){
return '<option value="' + item + '">' + item + '</option>'
}).join('');
$('#dropdown2').html(html);
});
});
// ]]></script>
当用户从下拉列表1中快速选择不同的值并且响应顺序不正确时,就会出现问题。 您可能最终在dropdown2中具有无效值。 解决此问题的一种方法是禁用dropdown1,直到响应返回,以防止用户选择其他值。 不幸的是,由于用户无法与dropdown1输入进行交互,因此这会使应用程序的响应速度降低。 那就是FRP给您一个想法–如果您可以使这些响应变得可观察 ,例如事件流 ,您希望它仅对流中的最新响应做出反应 ,该怎么办? 有两个流行的FRP JavaScript库: Bacon.js和Rx.js。 在此示例中,我将使用Rx.js。 想法是一旦将它们放入可观察的事件流中就推动这些响应承诺。 一旦将这些承诺分解为我们的应用程序将要观察的另一个流,该库将解开这些承诺。 它将仅对最后一个事件作出反应。 Rx.js没有现成的事件总线,您可以在其中输入值并进行观察。 (与Bacon.js不同,在那里您有一个Bus类可以做到这一点)。 但是,您可以轻松创建自己的事件总线,或者找到一个已经等来实现这一个 。 借助该库,我们的代码看起来非常简单:
<script>// <![CDATA[
var bus = new MessageQueue();
$('#dropdown1').change(function () {
var selected = $(this).val();
var promise = $.ajax('/path/to/your/server', {
data: {value: selected}
});
bus.push(promise);
});
bus.flatMapLatest(function(promise){
return Rx.Observable.fromPromise(promise)
}).subscribe(function(data){
var html = $.map(data, function(item){
return '<option value="' + item + '">' + item + '</option>'
}).join('');
$('#dropdown2').html(html);
})
// ]]></script>
首先,我们创建一个称为bus的可观察流,我们可以将值推送到该流。 然后,我们订阅流,以便我们可以在值(响应)更改时做出反应。 flatMapLatest过滤器方法是在这里发挥所有魔力的一种方法。 它要做的就是在将其解析为另一个可观察的流时解开承诺。 但是,在等待承诺得到解决时,如果之后又出现另一个承诺,它将改为切换到该流。 无需禁用下拉输入。 如果用户错误地选择了一个值,则用户可以尝试选择另一个值,而不必等待先前的响应返回。 确保第二个下拉列表同步。
最后的想法
对于像这样的小型应用程序,FRP实际上没有提供比功能编程或过程编程更多的优势。 但是,随着系统在诸如交互组件数量,并发性,异步操作(和回调)数量之类的这些方面进行扩展时,FRP范式开始提供抽象,以帮助开发人员不必担心时变表达式的触发器重新评估。 希望本文对您有所帮助,并且足以使您对FRP有所了解。 请享用。
翻译自: https://www.javacodegeeks.com/2014/08/functional-reactive-programming-and-javascript.html