[Ramda] Refactor a Promise Chain to Function Composition using Ramda
Promise chains can be a powerful way to handle a series of transformations to the results of an async call. In some cases, additional promises are required along the way. In cases where there are no new promises, function composition can reduce the number of dot chained thens you need. In this lesson, we'll look at how to take a promise chain, and reduce it down with function composition.
const deckUrl = 'https://deckofcardsapi.com/api/deck/new/shuffle/?cards=AS,2S,5C,3C,KD,AH,QH,2C,KS,8C'; fetch(deckUrl)
.then(res => res.json())
.then(deck => fetch(`https://deckofcardsapi.com/api/deck/${deck.deck_id}/draw/?count=10`)
.then(res => res.json())
.then(deck => deck.cards)
.then(cards => cards.filter(c => c.suit === 'CLUBS'))
.then(cards => cards.map(c => c.image))
.then(cards => cards.sort((c1, c2) => c1.value - c2.value)))
.then(cards => cards.map(u => `<img width="" src="${u}"/>`).join(''))
.then(imgString => {
document.querySelector('#cards').innerHTML = `<div>${imgString}</div>`
})
We want to use Ramda to improve code:
Using R.prop and R.map:
// from
.then(deck => deck.cards) // to
.then(prop('cards')) // from
.then(cards => cards.map(c => c.image)) //to
.then(map(prop('image')))
Using R.propEq and R.filter:
// from
.then(cards => cards.filter(c => c.suit === 'CLUBS')) //to
.then(filter(propEq('suit', 'CLUBS')))
Using R.sortBy:
// from
.then(cards => cards.sort((c1, c2) => c1.value - c2.value))) // to
.then(sortBy(prop('value'))))
Using R.compose:
// from
.then(cards => cards.map(u => `<img width="" src="${u}"/>`).join('')) // to
.then(compose(join(''), map(u => `<img width="" src="${u}"/>`)))
Now it looks like:
const {prop, filter, map, sortBy, propEq, join, compose, pluck} = R
const deckUrl = 'https://deckofcardsapi.com/api/deck/new/shuffle/?cards=AS,2S,5C,3C,KD,AH,QH,2C,KS,8C'
fetch(deckUrl)
.then(res => res.json())
.then(deck => fetch(`https://deckofcardsapi.com/api/deck/${deck.deck_id}/draw/?count=10`)
.then(res => res.json())
.then(prop('cards'))
.then(filter(propEq('suit', 'CLUBS')))
.then(map(prop('image')))
.then(sortBy(prop('value')))
.then(compose(join(''), map(u => `<img width="" src="${u}"/>`)))
.then(imgString => {
document.querySelector('#cards').innerHTML = `<div>${imgString}</div>`
})
We can also pull out each step as a function.
const {prop, filter, map, sortBy, propEq, join, compose, pluck} = R
const deckUrl = 'https://deckofcardsapi.com/api/deck/new/shuffle/?cards=AS,2S,5C,3C,KD,AH,QH,2C,KS,8C'
const getId = prop('deck_id');
const drawCards = id => fetch(`https://deckofcardsapi.com/api/deck/${id}/draw/?count=10`)
.then(res => res.json());
const getCards = prop('cards');
const justClubs = filter(propEq('suit', 'CLUBS'));
const sortByValue = sortBy(prop('value'));
const getImages = map(prop('image'));
const toImgString = compose(join(''), map(u => `<img width="" src="${u}"/>`));
const render = imgString => {
document.querySelector('#cards').innerHTML = `<div>${imgString}</div>`
};
fetch(deckUrl)
.then(res => res.json())
.then(getId)
.then(drawCards)
.then(getCards)
.then(justClubs)
.then(getImages)
.then(sortByValue)
.then(toImgString)
.then(render);
Using R.pluck to replace R.map(R.prop(''));
const getImages = pluck('image');
const {prop, filter, map, sortBy, propEq, join, compose, pluck} = R
const deckUrl = 'https://deckofcardsapi.com/api/deck/new/shuffle/?cards=AS,2S,5C,3C,KD,AH,QH,2C,KS,8C'
const getId = prop('deck_id');
const drawCards = id => fetch(`https://deckofcardsapi.com/api/deck/${id}/draw/?count=10`)
.then(res => res.json());
const getCards = prop('cards');
const justClubs = filter(propEq('suit', 'CLUBS'));
const sortByValue = sortBy(prop('value'));
const getImages = pluck('image');
const toImgString = compose(join(''), map(u => `<img width="" src="${u}"/>`));
const render = imgString => {
document.querySelector('#cards').innerHTML = `<div>${imgString}</div>`
};
const transformData = compose(toImgString, getImages, sortByValue, justClubs, getCards)
fetch(deckUrl)
.then(res => res.json())
.then(getId)
.then(drawCards)
.then(compose(render, transformData));
[Ramda] Refactor a Promise Chain to Function Composition using Ramda的更多相关文章
- [Ramda] Convert a QueryString to an Object using Function Composition in Ramda
In this lesson we'll use a handful of Ramda's utility functions to take a queryString full of name/v ...
- [Ramda] Refactor to a Point Free Function with Ramda's useWith Function
Naming things is hard and arguments in generic utility functions are no exception. Making functions ...
- [Typescript] Promise based delay function using async / await
Learn how to write a promise based delay function and then use it in async await to see how much it ...
- [Javascript] Understand Function Composition By Building Compose and ComposeAll Utility Functions
Function composition allows us to build up powerful functions from smaller, more focused functions. ...
- [Ramda] Convert a Promise.all Result to an Object with Ramda's zip and zipObj
In this lesson, we'll use Promise.all to get an array that contains the resolved values from multipl ...
- [Ramda] Refactor to Point Free Functions with Ramda using compose and converge
In this lesson we'll take some existing code and refactor it using some functions from the Ramda lib ...
- Function Composition vs Object Composition
In functional programming, we create large functions by composing small functions; in object-oriente ...
- [Ramda] Create a Query String from an Object using Ramda's toPairs function
In this lesson, we'll use Ramda's toPairs function, along with map, join, concatand compose to creat ...
- [Ramda] Filter an Array Based on Multiple Predicates with Ramda's allPass Function
In this lesson, we'll filter a list of objects based on multiple conditions and we'll use Ramda's al ...
随机推荐
- hdu 2795 Billboard(线段树单点更新)
Billboard Time Limit: 20000/8000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total ...
- 看好腾讯,鄙视百度(腾讯的核心竞争力,不是超过10亿的QQ的注册用户,也不是某一项产品、技术方面优势,而是“耐心”:懂得在合适的时间推出合适的产品。”)
百度,自始至终只是一个低劣的模仿者,且一切向前看,完全违背了一个搜索引擎所应该遵循的基本原则.谁给的钱多就能搜着谁,这跟贩毒有什么区别? 腾讯也在模仿别人,但是,它是模仿然后超越.在中国互联网发展历史 ...
- Linux 网卡驱动学习(九)(层二转发)
1.mac 地址表的自学习过程 port1上的A计算机要与port2上的B计算机通信时,A发到交换机上,交换机收到信息后,交换机先记录发port1所相应的a的mac地址并记录在自己的mac表中,然后再 ...
- 2. Dubbo和Zookeeper的关系
转自:https://www.cnblogs.com/hirampeng/p/9540243.html Dubbo建议使用Zookeeper作为服务的注册中心. 1. Zookeeper的作用: ...
- 学习笔记(三):jQuery之DOM
1.jQuery属性. 获取元素属性的语法: attr(name) 例子:$("#img1").attr("src"); 设 ...
- PatentTips - Resource partitioning and direct access utilizing hardware support for virtualization
BACKGROUND The present disclosure relates to the resource management of virtual machine(s) using har ...
- Day2:列表、元组
一.列表 1.定义与访问元素(按索引) #!/usr/bin/env python # -*- coding:utf-8 -*- # Author:Hiuhung Wan list_a = [&quo ...
- Machine Learning With Spark学习笔记(提取10万电影数据特征)
注:原文中的代码是在spark-shell中编写运行的,本人的是在eclipse中编写运行,所以结果输出形式可能会与这本书中的不太一样. 首先将用户数据u.data读入SparkContext中.然后 ...
- Linux下开启关闭防火墙
一.Linux下开启/关闭防火墙命令 1) 永久性生效,重启后不会复原 开启: chkconfig iptables on 关闭: chkconfig iptables off 2) 即时生效,重 ...
- POJ 1595 Prime Cuts (ZOJ 1312) 素数打表
ZOJ:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=312 POJ:http://poj.org/problem?id=159 ...