{"id":27006,"library":"futoin-asyncsteps","title":"FutoIn AsyncSteps","description":"FutoIn AsyncSteps mimics traditional threads of execution in a single-threaded event loop, supporting cancellation, exit handlers, thread-local storage, and synchronization primitives like mutexes and throttles. Current stable version is 2.5.6, released under a stable maturity (status 3). It builds on the FTN12: FutoIn Async API v1.13 specification. Key differentiators include explicit step-based control flow (add, parallel, error handling) rather than Promises or async/await, though it integrates with Promises via as.await(). It is designed for both Node.js (>=8) and browser environments, providing ES5 CJS modules under es5/ and pre-built webpack dists under dist/. Synchronization primitives like Mutex are available for coordinated concurrent execution.","status":"active","version":"2.5.6","language":"javascript","source_language":"en","source_url":"https://github.com/futoin/core-js-ri-asyncsteps","tags":["javascript","futoin","async","steps","parallel","exceptions","loops","browser","webpack"],"install":[{"cmd":"npm install futoin-asyncsteps","lang":"bash","label":"npm"},{"cmd":"yarn add futoin-asyncsteps","lang":"bash","label":"yarn"},{"cmd":"pnpm add futoin-asyncsteps","lang":"bash","label":"pnpm"}],"dependencies":[],"imports":[{"note":"Default export is a factory function returning AsyncSteps instance. In CommonJS, use require('futoin-asyncsteps') directly.","wrong":"const $as = require('futoin-asyncsteps').default","symbol":"$as","correct":"import $as from 'futoin-asyncsteps'"},{"note":"AsyncSteps is a named export, not default. In CommonJS: const { AsyncSteps } = require('futoin-asyncsteps').","wrong":"import AsyncSteps from 'futoin-asyncsteps'","symbol":"AsyncSteps","correct":"import { AsyncSteps } from 'futoin-asyncsteps'"},{"note":"Mutex is a named export. In browser, it may require WeakMap polyfill.","wrong":"const Mutex = require('futoin-asyncsteps').Mutex","symbol":"Mutex","correct":"import { Mutex } from 'futoin-asyncsteps'"},{"note":"In browser, $as is a global; no import needed. Use script tag loading the dist.","wrong":"import $as from 'futoin-asyncsteps' in non-module script","symbol":"$as (browser)","correct":"<script src='dist/futoin-asyncsteps.min.js'></script>... $as(...)"}],"quickstart":{"code":"const $as = require('futoin-asyncsteps');\n\nconst root = $as();\nroot.add((as) => {\n    console.log('Step 1');\n    as.success('done');\n}).add((as, result) => {\n    console.log('Step 2 received:', result);\n    as.success();\n});\nroot.execute();","lang":"javascript","description":"Shows basic step execution chain with add() and success()."},"warnings":[{"fix":"Ensure exactly one call to as.success() or as.error() per step (or none for implicit success).","message":"Calling as.success() more than once or after as.error() in a step causes undefined behavior.","severity":"gotcha","affected_versions":">=2.0"},{"fix":"Include dist/polyfill-asyncsteps.js before using Sync primitives in legacy browsers.","message":"Synchronization primitives (Mutex, Throttle) require WeakMap polyfill in older browsers.","severity":"gotcha","affected_versions":">=2.0"},{"fix":"Use as.state for cross-step data, but be aware of unintended sharing when passing AsyncSteps instances or creating nested scopes.","message":"The as.state object is shared among all steps in the same AsyncSteps instance; mutations persist across steps.","severity":"gotcha","affected_versions":">=2.0"},{"fix":"Ensure error handling steps are added after as.await() to catch rejections.","message":"Using as.await() with a rejected Promise will trigger error handling in the AsyncSteps flow, not throw an unhandled rejection.","severity":"gotcha","affected_versions":">=2.0"},{"fix":"Assign to as.state inside each parallel add() callback to collect outputs.","message":"Parallel step results are not automatically merged; you must store results in as.state manually inside each parallel branch.","severity":"gotcha","affected_versions":">=2.0"}],"env_vars":null,"last_verified":"2026-05-01T00:00:00.000Z","next_check":"2026-07-30T00:00:00.000Z","problems":[{"fix":"Use `import $as from 'futoin-asyncsteps'` or `const $as = require('futoin-asyncsteps')`.","cause":"Imported default incorrectly (e.g., import { $as } instead of import $as).","error":"TypeError: $as is not a function"},{"fix":"Run `npm install futoin-asyncsteps` and ensure import path is correct.","cause":"Package not installed or wrong path in require/import.","error":"Cannot find module 'futoin-asyncsteps'"},{"fix":"Only call as.success() inside a step function passed to add(), parallel().add(), etc.","cause":"Calling as.success outside of a step callback (e.g., in the root scope or after step ends).","error":"as.success is not a function"}],"ecosystem":"npm","meta_description":null,"install_score":null,"install_tag":null,"quickstart_score":null,"quickstart_tag":null}