函数式反应型编程(FRP)

函数式反应型编程(FRP)

前言

当我们开始写项目的时候,总会遇到一些情景,比如定时任务,ajax请求,要求我们去请求大的文件或者图片这些,然后我们就发现,直接写代码,会出现加载缓慢,白屏这样的问题,众所周知,js是单线程的,所以js任务也是一个一个顺序执行的,就是同步执行,后一个任务必须等待前一个任务完成之后才能执行,就如前面所说的,如果前一个任务花费的时间很长,就会造成阻塞,给用户带来不好的体验,我们要解决这些问题,当我们等待但是又不要阻塞程序,所以就需要异步处理这些耗时间的任务。

1.处理异步的方法

假设有多个异步任务,且任务有依赖关系,后一个任务必须拿到前一个任务的执行结果才可以执行

作为刚刚入门学习的小白,比如我,最先能想到的就是函数调用了

(1)回调:容易造成回调地狱

回调是实现异步编程最简单的方法,我们可以在一个函数中调用其他函数,实现我们想要的逻辑

getData1(data1 => {
  getData2(data1, data2 => {
    getData3(data2, data3 => {
      getData4(data3, data4 => {
        getData5(data4, data5 => {
          // 终于取到data5了
        })
      })
    })
  })
})

乍一看,写的还可以,也达到了预期的效果,就是看起来不美观,而且还形成了回调地狱,但是如果里面出现很多问题,需要进行异常处理及各种逻辑检查呢,那这一块代码就会变得非常长,非常复杂,可能下次同事看见了你的代码,直接暴走。

为了让代码更具备可读性,Promise隆重登场。

(2)Promise:解决回调地狱

依旧来解决上面的问题

getData1(data1)
.then(data1 => {
   
   return getData2(data1);
})
.then(data2 => {
   
   return getData3(data2);
})
.then(data3 => {
   
   return getData4(data3);
})
.then(data4 => {
   
   return getData(data4);
})
.catch(err => {
   
	console.log(err);
})

我们直接一路链式调用,看起来更清楚明了,但是感觉这样调用也不是个办法。

你的上级询问,那还能做的更优雅吗?这可难住了我,喔喔喔,但是不要怕,es5的回调让我陷入地狱,但是我爬起来了,es6的Promise让我得到夸奖,es7这不是又出了好方法吗?让我们接下来看看es7的async/await吧。

(3)async/await:简化了逻辑,但是损失了异步带来的性能优势(比如把并行变成串行,增加了时间开销)

// 定义一个执行Async函数方法
async function getSSQ () {
   let a = await getData1(data1)
   let b = await getData2(a)
   let c = await getData3(b)
   let d = await getData4(c)
   let e = await getData5(d)
   console.log(d);
}

确实好用,也可以使用try…catch了,啊,这你想肯定能满足上级的要求了,又简单又优雅,小白一眼就看懂,async/await带着我走向了人生巅峰。

(4)各个方法优缺点总结

方法 优点 缺点
回调 简单逻辑处理很方便 逻辑复杂时容易造成回调地狱
Promise 1.状态改变就不会再变,任何时候都能得到确切的结果 2.写法符合思维逻辑 1.一旦创建,立即执行,中途无法取消 2.处于pending状态时,无法得知状态3.不设置回调函数,内部错误无法反映到外部
Async/await 1. 做到了串行的同步写法 2.代码清晰明了 1.做不到并行,除非await不在一个函数里面 2.没有了promise的方法,比如race() 3.没有Promise的reject方法,得写在try…catch中

代码非常简洁易读了,但是学海无涯,我发现现在有了一个新的技术,叫做FRP,看了一些文章,文章里面一直说有了FRP,就使用流来处理异步,把异步数据看成数据流来处理,会让事情更简单

那FRP到底是什么呢?

2.FRP是什么

首先让我们先使用FRP直接实现上述的需求

 function getSSQ() {
        let data1 = 1;
        return rxjs.from(getData(data1)).pipe(
            rxjs.operators.mergeMap(a =>
                rxjs.from(getData(a))
            ),
            rxjs.operators.mergeMap(b =>
                rxjs.from(getData(b))
            ),
            rxjs.operators.mergeMap(c =>
                rxjs.from(getData(c))
            ),
            rxjs.operators.tap(console.log),
            rxjs.operators.mergeMap(d =>
                rxjs.from(getData(d))
            ),
            rxjs.operators.tap(e => {
            }),
        );
    }
    getSSQ().subscribe({
        // next(x) { console.log('got value ' + x); },
        // error(err) { console.error('something wrong occurred: ' + err); },
        complete() { console.log('done'); }
    })

看不懂吧,看不懂没关系,只需要知道from是建立流的,mergeMap()是操作流的,subscribe是订阅流的,最后直接输出结果就好了,我们先来了解一下什么是FRP及实际应用,重点是学习FRP不同的思维方式

(1)概念

FRP(Functional Reactive Programming),也叫函数式响应式编程

函数反应式编程 &#

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值