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的更多相关文章

  1. [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 ...

  2. [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 ...

  3. [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 ...

  4. [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. ...

  5. [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 ...

  6. [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 ...

  7. Function Composition vs Object Composition

    In functional programming, we create large functions by composing small functions; in object-oriente ...

  8. [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 ...

  9. [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 ...

随机推荐

  1. ontouch-控件添加ontouch监听事件

    1,代码public class CalculatorViewPager extends ViewPager {}中 package com.android.calculator2; import a ...

  2. 笔记三:JS正则表达式

    正则表达式(英语:Regular Expression,在代码中常简写为regex.regexp或RE)使用单个字符串来描述.匹配一系列符合某个句法规则的字符串搜索模式.说白了正则表达式就是处理字符串 ...

  3. 【2017中国大学生程序设计竞赛 - 网络选拔赛 && hdu 6154】CaoHaha's staff

    [链接]点击打开链接 [题意] 给你一个面积,让你求围成这个面积最少需要几条边,其中边的连线只能是在坐标轴上边长为1的的线或者是两个边长为1 的线的对角线. [题解] 找规律题 考虑s[i]表示i条边 ...

  4. amazeui学习笔记--css(常用组件12)--面板Panel

    amazeui学习笔记--css(常用组件12)--面板Panel 一.总结 1.面板基本样式:默认的 .am-panel 提供基本的阴影和边距,默认边框添加 .am-panel-default,内容 ...

  5. Codeforces Round #100 E. New Year Garland (第二类斯特林数+dp)

    题目链接: http://codeforces.com/problemset/problem/140/E 题意: 圣诞树上挂彩球,要求从上到下挂\(n\)层彩球.已知有\(m\)种颜色的球,球的数量不 ...

  6. 1.3 Python基础知识 - 用户交互及传递参数

    一.用户交互 用户交互方面,每种开发语言都有不同的方式,例如shell语言用的是,“read -p "What is  your name ? " ”.python中是什么样子的呢 ...

  7. (转)Could not execute auto check for display colors using command /usr/bin/xdpyinfo. Check if the DISPL

    转自:http://blog.csdn.net/huashnag/article/details/9357517 Starting Oracle Universal Installer... Chec ...

  8. 【Codeforces Round #431 (Div. 1) B】

    [链接]h在这里写链接 [题意] 场上有 n 个点,它们分别向上与向右在不同时刻开始运动,相遇则改变移动方向,求最终这些点到达的坐标. [题解] 先把每个点的坐标都往它本该移动的方向相反的方向退ti个 ...

  9. C#利用反射机制,获取实例的属性和属性值

    C#利用反射,遍历获得一个类的所有属性名,以及该类的实例的所有属性的值 对应某个类的实例化的对象tc, 遍历获取所有属性(子成员)的方法(采用反射): Type t = tc.GetType();// ...

  10. [Node] Setup an Nginx Proxy for a Node.js App

    Learn how to setup an Nginx proxy server that sits in front of a Node.js app. You can use a proxy to ...