İşte Yüksek Dereceli Fonksiyonların Hayatınızı İyileştirebileceği 7 Yol – JSManifest

İşte Yüksek Dereceli Fonksiyonların Hayatınızı İyileştirebileceği 7 Yol – JSManifest

JavaScript’in temel yapı taşlarından biri işlevlerdir. JavaScript öğrenirken işlevlerin anlamı hakkında herkesin ilgisini çekmek için bu yeterlidir.

Ama fonksiyonlar fazla bundan daha ilgi çekici.

“Ne gibi” diye mi soruyorsun?

Onlar olabilir üst düzey fonksiyonlar— diğer işlevleri bağımsız değişken olarak alan işlevler veya çıktıları olarak işlevleri döndüren işlevler.

bir sürü var fonksiyonlar bu satırda devam ediyor – ve JavaScript farklı değil. JavaScript’te işlevler her yerde. Ve sen oldukları için kutsanmış hissetmeliler!

İşte Yüksek Dereceli Fonksiyonların Hayatınızı İyileştirmesinin 7 Yolu:

1. Mevcut Kodunuzu Geliştirirler

Görevi bir API’den kurbağaların listesini almak olan, döndürülen listeyi kurbağaların ortalama dil genişliğini hesaplamak için kullanan ve sonucu döndüren bir işlev düşünün.

Bir örnek şöyle bir şey olurdu:

import axios from 'axios'

const getFrogs = async (params) => {
  try {
    const response = await axios.get(
      'https://frogs-and-their-tongues.com',
      params,
    )
    const frogs = response.data.result
    return frogs
  } catch (error) {
    throw error
  }
}

const calcAverageWidthOfTongues = async (params) => {
  try {
    const frogs = await getFrogs(params)
    const tongueWidths = frogs.reduce((sum, frog) => {
      return sum + frog.tongueWidth
    }, 0)
    const averageWidth = tongueWidths / frogs.length
    return averageWidth
  } catch (error) {
    throw error
  }
}

calcAverageWidthOfTongues({
  username: 'bob',
  password: 'the_builder100',
})
  .then((result) => {
    console.log(result)
  })
  .catch((error) => {
    console.error(error)
  })

Şimdi olduğu gibi, yalnızca bir sayı döndürmekle sınırlıyız. Ama ya onu bir nesneye dönüştürmenin bir yolu olsaydı? orijinal işlevi değiştirmeden?

bu artırma daha iyi kontrol için çıktıyı özelleştirmek ve dönüştürmek için ek seçeneklere geçme yeteneğine sahip olmak:

import axios from 'axios'

const getFrogs = async (params) => {
  try {
    const frogs = await axios.get('https://frogs-and-their-tongues.com', params)
    return data
  } catch (error) {
    throw error
  }
}

const calcAverageWidthOfTongues = async (params) => {
  try {
    const frogs = await getFrogs(params)
    const tongueWidths = frogs.reduce((sum, frog) => {
      return sum + frog.tongueWidth
    }, 0)
    const averageWidth = tongueWidths / frogs.length
    return averageWidth
  } catch (error) {
    throw error
  }
}

const useTongueObj = (fn, options) => {
  return async (params) => {
    const newParams = { ...params }
    if (options.limit !== undefined) {
      newParams.limit = options.limit
    }

    let averageWidth = await fn(newParams)

    if (typeof options.multiplyBy === 'number') {
      averageWidth = averageWidth * options.multiplyBy
    }

    return {
      averageWidth,
      multiplied: typeof options.multiplyBy === 'number',
      size: averageWidth < 2 ? 'small' : 'large', 
    }
  }
}

const calcTongueWidths = useTongueObj(calcAverageWidthOfTongues, {
  multiplyBy: 2,
})

calcTongueWidths({ limit: 10 })
  .then((tongueObj) => {
    console.log(tongueObj)
    
  })
  .catch((error) => {
    console.log(result)
  })

2. Kıymetli Zamandan Tasarruf Sağlarlar

üst düzey işlevler değerli ve değerli zamandan tasarruf etmenize yardımcı olabilir

Bunu biraz daha vurgulamak istediğim için gerçek hayattan bir örnek vereyim.

Üst düzey fonksiyonların en büyük faydalarından biri, doğru kullanıldığında tasarruf sağlamasıdır. çok fazla için zamanın sen ve için çevrendekiler.

Benim işimde kullandık tepki vermek Bildirimleri görüntülemek için biz onu kullandık her yerde. Ayrıca, hızlı son dakika UX kararları için harika kaçış kapakları da yaparlar: “Bu hatayı nasıl ele almalıyız? Sadece bir kadeh kaldırma bildirimi göster!” Tamamlandı.

Ancak, uygulama büyüdükçe ve karmaşıklık seviyesi üstümüze gelmeye başladığında, bildirimlerimizin çok sık olmaya başladığını fark etmeye başladık. Bu iyi, ancak yinelemeleri önlemenin bir yolu yoktu. Bu, bazı tost bildirimlerinin, açık olduklarında bile ekranda birden çok kez göründüğü anlamına geliyordu. tam olarak aynı üstündeki tost gibi.

Böylece, aktif tost bildirimlerinin kaldırılmasına yardımcı olmak için kitaplığın sağladığı API’den yararlandık. İD kullanarak tost.dismiss().

Önümüzdeki kısımları açıklamak için, devam etmeden önce tostları içe aktardığımız dosyayı göstermek iyi bir fikir olabilir:

import React from 'react'
import { GoCheck, GoAlert } from 'react-icons/go'
import { FaInfoCircle } from 'react-icons/fa'
import { MdPriorityHigh } from 'react-icons/md'
import { toast } from 'react-toastify'





export const toastIds = {
  
  internetOnline: 'internet-online',
  internetOffline: 'internet-offline',
  retryInternet: 'internet-retry',
}


const getDefaultOptions = (options) => ({
  position: toast && toast.POSITION.BOTTOM_RIGHT,
  ...options,
})

const Toast = ({ children, success, error, info, warning }) => {
  let componentChildren
  
  if (!React.isValidElement(children) && typeof children !== 'string') {
    componentChildren = 'An error occurred'
  } else {
    componentChildren = children
  }
  let Icon = GoAlert

  if (success) Icon = GoCheck
  if (error) Icon = GoAlert
  if (info) Icon = FaInfoCircle
  if (warning) Icon = MdPriorityHigh

  return (
    <div style={{ paddingLeft: 10, display: 'flex', alignItems: 'center' }}>
      <div style={{ width: 30, height: 30 }}>
        <Icon style={{ color: '#fff', width: 30, height: 30 }} />
      </div>
      <div style={{ padding: 8, display: 'flex', alignItems: 'center' }}>
        &nbsp;&nbsp;
        <span style={{ color: '#fff' }}>{componentChildren}</span>
      </div>
    </div>
  )
}

export const success = (msg, opts) => {
  return toast.success(<Toast success>{msg}</Toast>, {
    className: 'toast-success',
    ...getDefaultOptions(),
    ...opts,
  })
}

export const error = (msg, opts) => {
  return toast.error(<Toast error>{msg}</Toast>, {
    className: 'toast-error',
    ...getDefaultOptions(),
    ...opts,
  })
}

export const info = (msg, opts) => {
  return toast.info(<Toast info>{msg}</Toast>, {
    className: 'toast-info',
    ...getDefaultOptions(),
    ...opts,
  })
}

export const warn = (msg, opts) => {
  return toast.warn(<Toast warning>{msg}</Toast>, {
    className: 'toast-warn',
    ...getDefaultOptions(),
    ...opts,
  })
}

export const neutral = (msg, opts) => {
  return toast(<Toast warning>{msg}</Toast>, {
    className: 'toast-default',
    ...getDefaultOptions(),
    ...opts,
  })
}

Şimdi sabırlı ol, bunun çekici görünmeyebileceğini biliyorum. Ama söz veriyorum iki dakika içinde daha iyi olacak.

Ekranda daha önce bir tost olup olmadığını kontrol etmek için ayrı bir bileşende sahip olduğumuz şey buydu. Ve varsa, o tostu kaldırmaya ve yeni tostu yeniden görüntülemeye çalışacaktır.

import { toast } from 'react-toastify'

import {
  info as toastInfo,
  success as toastSuccess,
  toastIds,
} from 'util/toast'

const onOnline = () => {
  if (toast.isActive(toastIds.internetOffline)) {
    toast.dismiss(toastIds.internetOffline)
  }
  if (toast.isActive(toastIds.retryInternet)) {
    toast.dismiss(toastIds.retryInternet)
  }
  if (!toast.isActive(toastIds.internetOnline)) {
    toastSuccess('You are now reconnected to the internet.', {
      position: 'bottom-center',
      toastId: toastIds.internetOnline,
    })
  }
}

const onOffline = () => {
  if (!toast.isActive(toastIds.internetOffline)) {
    toastInfo('You are disconnected from the internet right now.', {
      position: 'bottom-center',
      autoClose: false,
      toastId: toastIds.internetOffline,
    })
  }
}

useInternet({ onOnline, onOffline })

return <App />

Bu iyi çalışıyordu – ancak, uygulama boyunca aynı şekilde değiştirilmesi gereken başka tostlarımız vardı. Yinelenenleri kaldırmak için bir tost bildirimi görüntüleyen her dosyayı gözden geçirmemiz gerekiyordu.

düşündüğümüzde her dosyadan geçiyor 2019’da bunun çözüm olmadığını hemen anladık. Yani biz baktık util/toast.js dosya ve bunun yerine sorunumuzu çözmek için yeniden düzenledi. İşte daha sonra nasıl göründüğü:

src/util/toast.js

import React, { isValidElement } from 'react'
import isString from 'lodash/isString'
import isFunction from 'lodash/isFunction'
import { GoCheck, GoAlert } from 'react-icons/go'
import { FaInfoCircle } from 'react-icons/fa'
import { MdPriorityHigh } from 'react-icons/md'
import { toast } from 'react-toastify'





export const toastIds = {
  
  internetOnline: 'internet-online',
  internetOffline: 'internet-offline',
  retryInternet: 'internet-retry',
}


const getDefaultOptions = (options) => ({
  position: toast && toast.POSITION.BOTTOM_RIGHT,
  ...options,
})

const Toast = ({ children, success, error, info, warning }) => {
  let componentChildren
  
  if (!isValidElement(children) && !isString(children)) {
    componentChildren = 'An error occurred'
  } else {
    componentChildren = children
  }
  let Icon = GoAlert
  if (success) Icon = GoCheck
  if (error) Icon = GoAlert
  if (info) Icon = FaInfoCircle
  if (warning) Icon = MdPriorityHigh
  return (
    <div style={{ paddingLeft: 10, display: 'flex', alignItems: 'center' }}>
      <div style={{ width: 30, height: 30 }}>
        <Icon style={{ color: '#fff', width: 30, height: 30 }} />
      </div>
      <div style={{ padding: 8, display: 'flex', alignItems: 'center' }}>
        &nbsp;&nbsp;
        <span style={{ color: '#fff' }}>{componentChildren}</span>
      </div>
    </div>
  )
}

const toaster = (function() {
  
  const ensurePreviousToastIsRemoved = (toastId) => {
    if (toastId) {
      if (toast.isActive(toastId)) {
        toast.dismiss(toastId)
      }
    }
  }

  
  const attemptGetToastId = (msg, opts) => {
    let toastId
    if (opts && isString(opts.toastId)) {
      toastId = opts.toastId
    } else if (isString(msg)) {
      
      toastId = msg
    }
    return toastId
  }

  const handleToast = (type) => (msg, opts) => {
    const toastFn = toast[type]
    if (isFunction(toastFn)) {
      const toastProps = {}
      let className = ''
      const additionalOptions = {}
      const toastId = attemptGetToastId(msg, opts)
      if (toastId) additionalOptions.toastId = toastId
      
      ensurePreviousToastIsRemoved(toastId)
      
      switch (type) {
        case 'success':
          toastProps.success = true
          className = 'toast-success'
          break
        case 'error':
          toastProps.error = true
          className = 'toast-error'
          break
        case 'info':
          toastProps.info = true
          className = 'toast-info'
          break
        case 'warn':
          toastProps.warning = true
          className - 'toast-warn'
          break
        case 'neutral':
          toastProps.warning = true
          className - 'toast-default'
          break
        default:
          className = 'toast-default'
          break
      }
      toastFn(<Toast {...toastProps}>{msg}</Toast>, {
        className,
        ...getDefaultOptions(),
        ...opts,
        ...additionalOptions,
      })
    }
  }

  return {
    success: handleToast('success'),
    error: handleToast('error'),
    info: handleToast('info'),
    warn: handleToast('warn'),
    neutral: handleToast('neutral'),
  }
})()

export const success = toaster.success
export const error = toaster.error
export const info = toaster.info
export const warn = toaster.warn
export const neutral = toaster.neutral

Her dosyayı gözden geçirmek yerine, en basit çözüm bir dosya oluşturmaktı. üst düzey fonksiyon. Bunu yapmak, rolleri “tersine çevirmemize” izin verdi, böylece dosyalar arasında arama yapmak yerine, tostlar üst düzey fonksiyonumuza yönelik.

Bu şekilde dosyalardaki kodlar olumsuzluk değiştirilmiş veya dokundu. Hala normal çalışıyorlar ve sonunda gereksiz kod yazmak için hiçbir yere gitmeden yinelenen tostları kaldırma yeteneği kazandık. Bu zaman tasarrufu.

3. Yaratma Yeteneği Veriyorlar “Özel Dünyalar

üst düzey işlevler özel dünyalar yaratabilir

“Özel dünyalar” ile ne demek istiyorum?

Peki, şu örneği düşünün:

const preparePeopleWithFavoriteColor = (color) => {
  const _people = []

  return {
    getPeople() {
      return _people
    },
    addPeople(people) {
      _people.push(...people)
    },
    addPerson(person) {
      _people.push(person)
    },
    gather(people) {
      if (Array.isArray(people)) {
        people.forEach((person) => {
          if (color === person.favoriteColor) {
            _people.push(person)
          }
        })
      }
    },
  }
}

const peopleWhoLoveRed = preparePeopleWithFavoriteColor('red')

axios
  .get('https://someapi.com/peoples')
  .then((response) => {
    const people = response.data.result

    if (people.length) {
      peopleWhoLoveRed.gather(people)
    }

    return axios
      .get('https://someapi.com/other-peoples')
      .then((response) => {
        const morePeople = response.data.result
        if (morePeople.length) {
          everyoneWhoLovesRed.gather(morePeople)
        }
        return
      })
      .then(() => {
        
        peopleWhoLoveRed.addPerson({
          nickName: 'jsmanifest',
          favoriteColor: 'red',
        })

        return axios.post('https://api.redlovers.com/v1/subscribers/', {
          people: peopleWhoLoveRed.getPeople(),
        })
      })
  })
  .catch((error) => {
    console.error(error)
  })

Snippet’te, hazırlamakPeopleWithFavoriteColor oluşturur özel Dünya sonraki işlevi arayana geri döndürmeden önce çağrıldığında bloğunun içinde. Bu “özel dünya”, çatışan ad kasalarıyla dış kapsamı kirletmez ve kendi özel değişkenler ve değerler.

Ayrıca, kendi oluşturduğu kendi arayüzü ve yerel api onu yönetmek insanlar liste. Kapsam dışında olacak asla içeride ne olduğunu bilmek – ve bunu yapmanın tek yolu, geri verdiği genel yöntemlere bağlıdır.

Yeterince sinsiyseniz, kod her çalıştığında size kırmızıyı seven kişilerin listesini göndermek için bu sevimli küçük bloklarda gizli bir API çağrısına gizlice girebilirsiniz – ve kullanıcılar bunu söyleyemezler çünkü bunu söyleyemezler. uygulamadaki başka hiçbir şeyi etkilemez.

4. Hızlı ve Kesin Çözümler Olarak Kullanılabilirler

En karanlık zamanlarda, uygulamanızda gözle görülür herhangi bir değişiklik olmadan kod sorunlarını çözmenin en hızlı yolu olabileceğinden, üst düzey işlevler genellikle hayatınızı kurtarabilir.

Bir keresinde, kullanıcıların bir şekilde gezinme çubuklarında hala bir “Gösterge Tablosu” düğmesi gördüğü bir sorunum vardı. sonrasında tepki uygulamamızda çıkış yaptılar. Gösterge tablosu düğmesi, yalnızca uygulama, kullanıcının zaten oturum açmış olduğunu algılarsa görünür olmalıydı. Gösterge tablosu düğmesini tıkladıklarında, kullanıcı gösterge tablosu sayfasına yönlendirilirler.

O sırada çıkış yapma yöntemi, profil sayfalarına gidip çıkış düğmesini tıklatmaktı. Düğmeye tıklandığında, tamamen çıkış yapmaları ve tekrar oturum açma sayfasına yönlendirilmeleri gerekirdi.

Fakat Niye oldu Gösterge Paneli düğme hala gezinme çubuğunda gösteriliyor mu? Kullanıcı oturumu kapattı ve sorunu ayıkladığımda, yerel depolama dahil istemcideki her şey olması gerektiği gibi temizlendi – ya da ben öyle düşündüm.

Sonra sorunun bazı bölümleri olduğunu fark ettim. redux durumu hala oradaydı. bu yeniden yönlendirme kullanıyordu gezinmek kullanıcıyı farklı bir rotaya yönlendirmek için optimize edilmiş tüm sayfayı yenilemeden. Bu, önbelleğe alma sorunlarına neden oldu.

Öyleyse, kullanıcı oturumu kapattıktan sonra redux’daki tüm durumun sıfırlandığından nasıl emin olabilirim?

Oturumu kapattıktan sonra, eylem türüyle bir eylem yaratıcısı göndermeyi redux’a sahibiz. ÇIKIŞ YAP bu, uygulamaya kullanıcının oturumu kapattığını bildirmelidir.

Bir çözüm sağlamaya acil odak noktam, eylem yaratıcısını bir şekilde değiştirmekti. Bu geliştirmeyi sağlamak için en iyi yer gibi görünüyordu.

Ve sonra bunun en iyi çözüm olmadığını anladım çünkü bir daha iyi çözüm: bir kullanın üst düzey fonksiyon (ancak olumsuzluk burada).

İşte yüksek dereceli fonksiyonların neden böyle olduğuna dair harika bir örnek güçlü JavaScript’te:

Kök redüktör dosyamız src/reducers/index.js bunu ihraç etti:

export default combineReducers({
  app,
  form: formReducer,
})

Daha sonra bir uyguladık üst düzey fonksiyon bunun yerine bunu sarmak ve bir sıfırlama durumu türünde bir eylemin olduğunu algıladığında mantık ÇIKIŞ YAP gönderilir:

const appReducer = combineReducers({
  app,
  form: formReducer,
})


const rootReducer = (state, action) => {
  if (['LOGOUT'].includes(action.type)) {
    state = undefined
  }
  return appReducer(state, action)
}

export default rootReducer

Bu, durumu ilk durumuna sıfırlar çünkü durumu yeniden atadık. Tanımsız. Redux, redüktörü tanımsız bir durumla arayacak ve uygulamanın ilk durumunu döndürecektir..

5. Manipüle Edilen Verileri Her Yerde Tutabilir, İşleyebilir ve İletebilir

daha yüksek dereceli işlevler, verileri işlemeye ve etrafa aktarmaya yardımcı olabilir

Üst düzey işlevlerle yapabileceğiniz en havalı şeylerden biri, özel bir veri önbelleği tutmak, onu manipüle etmek ve iletmektir. herhangi bir yer uygulamada istediğiniz gibi. Hiçbiri dışarıdan müdahale edilmeyecek.

Örneğin, erişim belirteçlerini depolamak için bir yer bulmak istiyorsanız, böylece belirteç kullanıcı oturumunun ortasında 30 dakika içinde sona erdiğinde, bu belirteci yenileyebilir ve daha fazla kullanım için yeniden ayarlayabilirsiniz:

const Api = function(params) {
  const _store_ = {
    accessToken: null,
  }

  return {
    getAccessToken() {
      return _store.accessToken
    },
    async login() {
      try {
        const response = await axios.post(
          'https://something.com/v1/auth',
          params,
        )
        return response.data
      } catch (error) {
        throw error
      }
    },
    async refreshToken() {
      try {
        const response = await axios.post(
          'https://something.com/v1/access_token/',
          params,
        )
        const { token } = response.data
        _store.accessToken = token
        return token
      } catch (error) {
        throw error
      }
    },
    setAccessToken(token) {
      if (token === undefined) {
        throw new Error('token is undefined')
      }
      _store.accessToken = token
    },
    
  }
}

const api = Api({
  username: 'bob',
  password: 'the_builder123',
})

api
  .refreshToken())
  .then((token) => console.log(token))
  .catch(console.error)

6. Size Bir Şeyin Yeni Sürümlerini Oluşturma Yeteneği Veriyor

Diyelim ki 4 eski yeğeninize her gün sizi rahatsız etmesini engellemek için bir RPG oyunu oluşturmaya karar verdiniz. Bu oyunda bir grup savaşçı yaratmaya karar verdiniz:

const characters = []

const Warrior = function createWarrior(name) {
  this.name = name
  this.hp = 100
  this.mp = 100
  this.defence = 60

  return {
    
    slash(target) {
      target.hp -= 35
      return target
    },
    
    
    battleCry() {
      this.defence += 100
      this.battleCryInterval = setInterval(() => {
        this.defence -= 1
      }, 1000)
      this.battleCryTimeout = setTimeout(() => {
        this.defence = 60
      }, 40000)
    },
  }
}

bir üst düzey fonksiyon önce savaşçıları oluşturmak için bir ad listesi kabul eder, ardından savaşçıları oluşturmaya yardımcı olan yeni bir işlev döndürür:

const massCreateWarriors = function(names) {
  return (onCreate) => {
    const warriors = []
    names.forEach((name) => {
      const newWarrior = new Warrior(name)
      if (onCreate) onCreate(newWarrior)
      warriors.push(newWarrior)
    })
    return warriors
  }
}

const prepareWarriors = massCreateWarriors(['bob', 'joe', 'sally', 'woodie'])

const newWarriors = prepareWarriors(function onCreate(newWarrior) {
  if (newWarrior.name === 'sally') {
    newWarrior.theme = 'red'
  }
  characters.push(newWarrior)
})

Her seferinde farklı karakterler için kod yazmak yerine, sizin için çok sayıda karakter oluşturmak için bir yardımcı işlev oluşturmak güzel değil mi?

7. Patronunuz ve İş Arkadaşlarınızla Sağlıklı Bir İlişki Geliştirmenize Yardımcı Olabilir

üst düzey işlevler, patronunuz ve iş arkadaşlarınız ile sağlıklı bir ilişki geliştirmenize yardımcı olabilir

Daha yüksek dereceli fonksiyonlar birçok problemin çözülmesine yardımcı olabilir. Bununla birlikte, kod boyutunu küçültme ve yeniden kullanılabilirlik gibi daha yüksek dereceli işlevlerin masaya getirebileceği birçok faydalı fayda ile, bu şekilde kullanıldığında çevrenizdeki insanlar üzerinde stres yaratma olasılığını artıracaksınız. İş arkadaşlarınız sizin yalnızca bir geliştirici değil, aynı zamanda harika şeyler yapmaya çalışan bir geliştirici olmanıza bayılacaklar. Ayrıca, yeni geliştiricilerin becerilerini geliştirmelerine yardımcı olmak için kodunuzu öğrenme olasılığını da *azaltırsınız**. Bu sizi ekip, patron ve bir bütün olarak şirket için son derece değerli kılar.

ve iş arkadaşlarınız mutlu olduğunda, büyük olasılıkla bedava çörek getirme havasında olacaklardır..

Çözüm

Ve bu yazının sonunu tamamlıyor! Umarım beğenmişsinizdir ve gelecekte benden daha fazla gönderi bekleyin!

Mutlu cumalar!

Bir cevap yazın

E-posta hesabınız yayımlanmayacak.