Async operations with cancellation and error handling
Enhanced async/await with cancellation support, progress tracking, and structured error handling
Async operations with cancellation and error handling.
Task provides structured async operations with built-in cancellation, progress tracking, and error handling. Unlike Promises, Tasks can be cancelled and provide detailed error context.
import { Task } from "functype/task"
// Synchronous task
const syncTask = Task.sync("myTask", () => computeValue())
// Async task
const asyncTask = Task.async("fetchData", async () => {
const response = await fetch(url)
return response.json()
})
// Run and get result
const result = await asyncTask.run() // TaskOutcome<T>
// Check outcome
if (result.isOk()) {
console.log(result.value)
} else {
console.error(result.error)
}
| Method | Description |
|---|---|
Task.sync(name, () => T) | Wrap synchronous computation |
Task.async(name, async () => T) | Wrap async computation |
Task.of(value) | Task that succeeds with value |
Task.fail(error) | Task that fails with error |
Task.fromPromise(name, promise) | Convert Promise to Task |
const task = Task.async("longOperation", async (signal) => {
// Check signal periodically
for (let i = 0; i < 1000; i++) {
if (signal.aborted) {
throw new Error("Cancelled")
}
await processChunk(i)
}
})
// Run with timeout
const result = await task.run({ timeout: 5000 })
// Manual cancellation
const controller = new AbortController()
const promise = task.run({ signal: controller.signal })
controller.abort() // Cancel the task
const task = Task.async("upload", async (signal, progress) => {
for (let i = 0; i <= 100; i += 10) {
await uploadChunk(i)
progress(i / 100) // Report progress 0-1
}
return "complete"
})
// Subscribe to progress
task.run({
onProgress: (p) => console.log(`${p * 100}% complete`),
})
// Map - transform success value
task.map((data) => data.items)
// FlatMap - chain tasks
Task.async("getUser", () => fetchUser(id)).flatMap((user) => Task.async("getPosts", () => fetchPosts(user.id)))
// Recover - handle errors
task.recover(defaultValue)
task.recoverWith((error) => Task.of(fallback))
Task returns TaskOutcome<T> which is either Ok<T> or Err<Error>:
const outcome = await task.run()
// Pattern matching
outcome.fold(
(error) => `Failed: ${error.message}`,
(value) => `Success: ${value}`,
)
// Type guards
if (outcome.isOk()) {
console.log(outcome.value)
}
// Extract with default
const value = outcome.orElse(defaultValue)
// Convert to other types
outcome.toEither() // Either<Error, T>
outcome.toOption() // Option<T>
outcome.toTry() // Try<T>
import { Do, $ } from "functype/do"
const result = Do(function* () {
const user = yield* $(Task.async("getUser", () => fetchUser()))
const posts = yield* $(Task.async("getPosts", () => fetchPosts(user.id)))
const comments = yield* $(Task.async("getComments", () => fetchComments(posts)))
return { user, posts, comments }
})
// TaskOutcome conversions
outcome.toEither() // Either<Error, T>
outcome.toOption() // Option<T>
outcome.toTry() // Try<T>
outcome.toPromise() // Promise<T>
// Create from other types
Task.fromEither(either)
Task.fromTry(tryValue)
See full API documentation at functype API docs