Posted on

Jōtai 介紹

什麼是 Jōtai?

Jōtai 是一個輕量級、易於使用的 JavaScript 狀態管理庫,特別設計來與 React 無縫整合。它提供了一種簡單而直觀的方式來管理應用程式中的狀態,並讓這些狀態在不同的組件之間共享。

Jōtai 的核心概念

  • Atom: Jōtai 中最基本的單位,用來儲存一個單一的狀態值。你可以將 Atom 視為一個可變的變數,但它具有反應式特性,當 Atom 的值改變時,所有訂閱它的組件都會自動更新。
  • 用於訂閱的 Hook: useAtom 是一個 React Hook,用來訂閱一個 Atom。當你使用 useAtom 時,你會得到兩個值:當前的 Atom 值和一個用於更新 Atom 值的函數。

Jōtai 的優勢

  • 狀態共享: Jōtai 可以輕鬆地將狀態共享給應用程式中的任何組件。
  • 反應式更新: 當 Atom 的值改變時,訂閱它的組件會自動更新。
  • 避免 prop drilling: 你不再需要通過層層嵌套的組件來傳遞 props。
  • 可測試性: Jōtai 的狀態是可測試的,這有助於你寫出更可靠的應用程式。

安裝Jōtai

# npm
npm i jotai

# yarn
yarn add jotai

# pnpm
pnpm add jotai

基本用法

import { atom } from 'jotai'

const countAtom = atom(0)

const countryAtom = atom('Japan')

const citiesAtom = atom(['Tokyo', 'Kyoto', 'Osaka'])

const animeAtom = atom([
  {
    title: 'Ghost in the Shell',
    year: 1995,
    watched: true
  },
  {
    title: 'Serial Experiments Lain',
    year: 1998,
    watched: false
  }
])

從同一元件讀取和寫入

當原子在同一元件中同時讀取和寫入時,為簡單起見,請使用組合 useAtom 鉤子。

import { useAtom } from 'jotai'

const AnimeApp = () => {
  const [anime, setAnime] = useAtom(animeAtom)

  return (
    <>
      <ul>
        {anime.map((item) => (
          <li key={item.title}>{item.title}</li>
        ))}
      </ul>
      <button onClick={() => {
        setAnime((anime) => [
          ...anime,
          {
            title: 'Cowboy Bebop',
            year: 1998,
            watched: false
          }
        ])
      }}>
        Add Cowboy Bebop
      </button>
    <>
  )
}

從單獨的元件讀取和寫入

當僅讀取或寫入原子值時,可使用 useAtomValue 和 useSetAtom hooks 。

import { useAtomValue, useSetAtom } from 'jotai'

const AnimeList = () => {
  const anime = useAtomValue(animeAtom)

  return (
    <ul>
      {anime.map((item) => (
        <li key={item.title}>{item.title}</li>
      ))}
    </ul>
  )
}

const AddAnime = () => {
  const setAnime = useSetAtom(animeAtom)

  return (
    <button onClick={() => {
      setAnime((anime) => [
        ...anime,
        {
          title: 'Cowboy Bebop',
          year: 1998,
          watched: false
        }
      ])
    }}>
      Add Cowboy Bebop
    </button>
  )
}

const ProgressTracker = () => {
  const progress = useAtomValue(progressAtom)

  return (
    <div>{Math.trunc(progress * 100)}% watched</div>
  )
}

const AnimeApp = () => {
  return (
    <>
      <AnimeList />
      <AddAnime />
      <ProgressTracker />
    </>
  )
}
Posted on

Engine.io介紹

Engine.io介紹

Socket.io是在engine.io的基礎上去實作的
Gitlab連結: Engine.IO: the realtime engine
engine.iosocket.io提供跨瀏覽器/跨設備的雙向通信的底層庫。engine.io使用了WebsocketXHR方式封裝了一套socket協議。在低版本的瀏覽器中,不支持Websocket,為了兼容使用長輪詢( polling )替代。

關於長輪詢可參考我的另一篇文章:WebSocket與Ajax的不同
過去WebSocket未出來時,許多聊天室使用的都是長輪詢的方式去實作,而engine.io則可依據客戶端環境兼容使用這兩種方式。
Continue reading Engine.io介紹

Posted on

Redis Sentinel

Sentinel特性

Redis Sentinel為Redis提供高可用性。實際上,這意味著使用Sentinel可以創建Redis部署,該部署可以在沒有人工干預的情況下抵抗某些類型的故障。

Redis Sentinel還提供其他附帶任務,例如監視,通知,並充當客戶端的配置提供程序。

這是宏觀上Sentinel功能的完整列表(即,大圖):

監控。Sentinel會不斷檢查您的主實例和副本實例是否按預期工作。
通知。Sentinel可以通過API通知系統管理員或其他計算機程序,其中一個受監視的Redis實例出了問題。
自動故障轉移。如果主服務器未按預期工作,則Sentinel可以啟動故障轉移過程,在該過程中將副本升級為主服務器,將其他附加副本重新配置為使用新的主服務器,並通知使用Redis服務器的應用程序要使用的新地址。連接時。
配置提供程序。Sentinel充當客戶端服務發現的授權來源:客戶端連接到Sentinels,以詢問負責給定服務的當前Redis主服務器的地址。如果發生故障轉移,Sentinels將報告新地址。

Redis Sentinel是一個分佈式系統:

Sentinel本身設計為在有多個Sentinel進程協同合作的配置中運行。具有多個Sentinel進程進行協作的優點如下:

當多個哨兵就給定的主機不再可用這一事實達成共識時,將執行故障檢測。這降低了誤報的可能性。
即使不是所有的Sentinel進程都在工作,Sentinel仍能正常工作,從而使系統能夠應對故障。畢竟,擁有故障轉移系統本身就是一個單點故障,這沒有任何樂趣。
Continue reading Redis Sentinel

Posted on

npm module – ioredis介紹

Redis介紹

Redis是REmote DIctionary Server(遠程字典服務器)的縮寫,它以字典結構(key-value鍵值對結構)存儲數據,並允許其他應用通過TCP協議讀寫字典中的內容。所以,redis是一個key-value存儲系統,或者說是一個key-value數據庫。

Redis的內存存儲和持久化Redis數據庫中的所有數據都存儲在內存中。由於內存的讀寫速度遠快於硬盤,因此Redis在性能上對比其他基於硬盤存儲的數據庫有非常明顯的優勢,在一臺普通的筆記本電腦上,edis可以在一秒內讀寫超過十萬個鍵值。將數據存儲在內存中也有問題,例如,程序退出後內存中的數據會丟失。不過 Redis提供了對持久化的支持,即將可以內存中的數據異步寫入到硬盤中,同時不影響繼續提供服務

ioredis介紹


ioredis是一個功能強大的功能強大的Redis客戶,已被世界上最大的在線商務公司阿里巴巴和許多其他了不起的公司所使用。
Continue reading npm module – ioredis介紹

Posted on

加解密用的模組 – yeast

模組資訊

模組介紹

yeast是唯一的ID生成器。它的主要目的是生成可用於緩存清除的唯一ID。通常的做法是使用時間戳記,但是使用時間戳記有幾個缺點。

  • 時間戳已經是13個字符了。這可能對1個請求無關緊要,但是如果您發出數百個請求,則這會迅速增加帶寬和處理時間。
  • 它不夠獨特。如果您緊接彼此生成兩個標記,則它們將是相同的,因為計時精度限制為毫秒。

yeast通過以下方式解決了這兩個問題:

  • Compressing the generated timestamp using a custom encode() function that returns a string representation of the number.
  • Seeding the id in case of collision (when the id is identical to the previous one).

模組安裝

npm install –save yeast

模組使用

加載函式庫
‘use strict’;

var yeast = require(‘yeast’);
產生惟一識別ID

console.log(yeast(), yeast(), yeast()); // outputs: KyxidwN KyxidwN.0 KyxidwN.1

setTimeout(function () {
  console.log(yeast()); // outputs: KyxidwO
});

yeast.encode(num)

yeast.encode(+new Date()); // outputs: Kyxjuo1

yeast.decode(str)

var id = yeast(); // holds the value: Kyxl1OU

yeast.decode(id); // outputs: 1439816226334