Никогда больше не используйте если. Прототип, тест и код. КРАСНЫЙ-ЗЕЛЕНЫЙ-СИНИЙ, как говорит дядя Боб.
Введение
Конечные автоматы — полезная концепция в информатике и программировании, и они часто используются для моделирования поведения систем. В этом путешествии я исследую этот новый способ программирования, чтобы ответить на такие вопросы, как что такое конечные автоматы, как они работают, как я могу внедрить htem в свой рабочий процесс.
Конечный автомат — это математическая модель вычислений, которая представляет поведение системы как последовательность состояний и переходов между этими состояниями. В любой момент времени конечный автомат находится в определенном состоянии, и при выполнении определенных условий он может перейти в новое состояние. Конечные автоматы могут быть реализованы различными способами, например с помощью оператора switch или серии операторы if-else. С другой стороны, конечные автоматы позволяют абстрагировать методы/функции, охранники (если-иначе) и разработчики могут реализовать после определения конечного автомата логику системы. Раньше я говорил, что это промышленный способ программирования в противоположность ремесленной модели.
Библиотека XState — лучшая реализация конечных автоматов. Это идет еще дальше, поскольку они реализуют диаграммы состояний, где вы можете иметь события, дочерние конечные автоматы, параллельные состояния, например.
Поэтому я черпаю вдохновение в этой библиотеке, чтобы создать свою собственную единственную цель создания синхронной функции. Это единственное, чего не хватает в этой библиотеке.
Я изо всех сил стараюсь следовать синтаксису XState, чтобы вы могли использовать его с Stately Editor.
Функции
NB: Только для функций синхронизации
Если вы хотите использовать функции диаграммы состояний, такие как вложенные состояния, параллельные состояния, состояния истории, действия, вызываемые службы, отложенные переходы, временные переходы и т. д., используйте XState.
Быстрый старт
Монтаж
npm i @bemedev/fsf //or yarn add @bemedev/fsf //or pnpm add @bemedev/fsf
Использование (машина)
import { describe, expect, test } from 'vitest'; import { createLogic, interpret } from '@bemedev/fsf'; describe('#4: Complex, https query builder', () => { type Context = { apiKey?: string; apiUrl?: string; url?: string; }; type Events = { products?: string[]; categories?: string[] }; const queryMachine = createLogic( { schema: { context: {} as Context, // Add null option to make arguments optionals events: {} as Events | null, data: {} as string, }, context: {}, initial: 'preferences', states: { preferences: { always: { actions: ['setUrl', 'setApiKey', 'startUrl'], target: 'categories', }, }, categories: { always: [ { cond: 'hasCategories', target: 'products', actions: 'setCategories', }, 'products', ], }, products: { always: [ { cond: 'hasProducts', target: 'final', actions: 'setProducts', }, 'final', ], }, final: { data: 'query', }, }, }, { strict: true, actions: { setApiKey: ctx => { ctx.apiKey = '123'; }, setUrl: ctx => { ctx.apiUrl = 'https://example.com'; }, startUrl: ctx => { const { apiUrl, apiKey } = ctx; ctx.url = `${apiUrl}?apikey=${apiKey}`; }, setCategories: (ctx, { categories }) => { const _categories = categories?.join(','); ctx.url += `&categories=${_categories}`; }, setProducts: (ctx, { products }) => { const _products = products?.join(','); ctx.url += `&categories=${_products}`; }, }, guards: { hasCategories: (_, { categories }) => !!categories && categories.length > 0, hasProducts: (_, { products }) => !!products && products.length > 0, }, datas: { query: ctx => ctx.url, }, }, ); const func = interpret(queryMachine); test('#1: no args', () => { // So here, arguments are optionals ! expect(func()).toBe('https://example.com?apikey=123'); }); test('#2: categories', () => { expect(func({ categories: ['a', 'b'] })).toBe( 'https://example.com?apikey=123&categories=a,b', ); }); test('#3: products', () => { expect(func({ products: ['a', 'b'] })).toBe( 'https://example.com?apikey=123&categories=a,b', ); }); test('#4: categories and products', () => { expect(func({ products: ['a', 'b'], categories: ['c', 'd'] })).toBe( 'https://example.com?apikey=123&categories=c,d&categories=a,b', ); }); });