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));

  • 相关阅读:
    [HTML5] document.hidden
    在vue页面中设置resize事件
    document之ES6解构
    vue中mixins的使用方法和注意点---mixins第二篇(异步请求的情况)
    vue中mixins的使用方法和注意点---mixins第一篇
    vue中路由重定向redirect
    如何理解dispatch( 'tagsView/delAllViews',null,{root:true} )里面的root:true
    vue计算属性computed中的get和set的使用
    splice(0)的奇妙用法
    4月5日学习日志
  • 原文地址:https://www.cnblogs.com/Answer1215/p/6497572.html
Copyright © 2011-2022 走看看