zoukankan      html  css  js  c++  java
  • [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="100" 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="100" src="${u}"/>`).join(''))
    
    // to
    .then(compose(join(''), map(u => `<img width="100" 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="100" 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="100" 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="100" 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));

  • 相关阅读:
    前端程序员的进阶
    字符集的知识
    通晓多种编程语言的程序员,真香?
    理解 Docker
    免费开源软件的潜在安全风险
    技术编程人员成长的 9 个段位
    如何更好的设计 RESTful API
    selenium环境搭建:
    自动化测试有哪些?
    删除书籍:
  • 原文地址:https://www.cnblogs.com/Answer1215/p/6497572.html
Copyright © 2011-2022 走看看