[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 then
s 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 ...
随机推荐
- 鸟哥的Linux私房菜-----16、程序与资源管理
watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/ ...
- Android时间戳与字符串相互转换
import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.Date; public cl ...
- 24. Spring Boot 事务的使用
转自:https://blog.csdn.net/catoop/article/details/50595702
- 学习笔记:Vue——动态组件&异步组件
动态组件 01.在动态组件上使用keep-alive,保持组件的状态,以避免反复重渲染导致的性能问题. <!-- 失活的组件将会被缓存!--> <keep-alive> < ...
- v-for一定要与v-bind:key="id"连用
1. v-for: <div v-for="(item,index) in todolist" v-bind:key="item.id"> < ...
- COGS——C2098. Asm.Def的病毒
http://www.cogs.pro/cogs/problem/problem.php?pid=2098 ★☆ 输入文件:asm_virus.in 输出文件:asm_virus.out ...
- 人工智能计算器AI Calculator 3.3.0 具体破解思路&教程
人工智能计算器AI Calculator 3.3.0 具体破解思路&教程 [文章标题]:人工智能计算器AI Calculator 3.3.0 具体破解思路&教程 [文章作者]: Eri ...
- finalkeyword对JVM类载入器的影响
众所周知,当訪问一个类的变量或方法的时候.假设没有初始化该类.就会先去初始化一个类 可是,当这个类的变量为final的时候,就不一定了 请看以下的样例 package com.lala.shop; i ...
- Android多线程研究(6)——多线程之间数据隔离
在上一篇<Android多线程研究(5)--线程之间共享数据>中对线程之间的数据共享进行了学习和研究,这一篇我们来看看怎样解决多个线程之间的数据隔离问题,什么是数据隔离呢?比方说我们如今开 ...
- RMAN-03002、RMAN-06059
使用RMAN备份的时候无法正常备份,抛出以下错误: RMAN-03002: failure of backup command at 04/20/2015 18:55:45 RMAN-06059: e ...