API - YannickDot/Taskorama GitHub Wiki
Instance methods
constructor
// create a Task
const myTimeoutTask = Task(function (reject, resolve) {
let timer = setTimeout(function () {
resolve(42) // complete task succesfully with value '42' after 3s
}, 3000)
// execute `cancel` to stop the timeout
let cancel = () => clearTimeout(timer)
return {cancel}
})
.fork(errorEffect, successEffect)
myTimeoutTask
.fork(console.error, console.log)
// logs : 42
.run(successEffect)
.run(myCb)
is an alias for .fork(console.error, myCb)
myTimeoutTask
.run(console.log)
// logs : 42
.map()
myTimeoutTask
.map(x => x * 2)
.fork(console.error, console.log)
// logs : 84
.ap()
Task.of(x => x * 2)
.ap(Task.of(42))
.fork(console.error, console.log)
// logs: 84
.chain() / .flatMap()
myTimeoutTask
.chain(val => Task.of(val * 2))
.flatMap(val => Task.of(val + 1))
.fork(console.error, console.log)
// logs: 85
.then()
myTimeoutTask
.then(x => x * 2)
.then(val => Task.of(val + 1))
.fork(console.error, console.log)
// logs: 85
.catch()
myTimeoutTask
.then(x => {
throw 'argh'
})
.then(x => 42)
.catch(err => "Cool, it's fine now.")
.fork(console.error, console.log)
// logs: "Cool, it's fine now."
Static methods
Task.of / Task.resolve
Creates a task that completes immediately with the passed value.
const task = Task.of(200)
task.fork(console.error, console.log)
// logs: 200
Task.reject
Creates a task that rejects immediately with the passed value.
const task = Task.reject(404)
task.fork(console.error, console.log)
// logs error: 404
Task.do(* generatorFn)
Using JavaScript's generators to introduce a synchronous-looking syntax for chaining Tasks. This is inspired by Async/Await for Promises and Haskell's do notation for Monads.
const fetchJSON = url => Task.fetch(url).then(r => r.json())
const main = Task.do(function *() {
const posts = yield fetchJSON('/posts')
const users = yield fetchJSON('/users')
yield Task.wait(2000) // Lets pause for 2 sec.
return {posts, users}
})
// -> 'main' is a Task
main
.fork(console.error, console.log)
// -> logs: { posts: [...], users: [...] }
Task.fetch(url) (browser only)
Creates a task that makes a request on the specified url. It resolves with a Response object.
The Response
object exposes the following readers at the moment :
.json()
.text()
Task.fetch
try to mimic the behavior of the fetch API
const url = 'https://jsonplaceholder.typicode.com/users'
const requestTask = Task.fetch(url)
.then(response => response.json())
const runningRequest = requestTask.fork(console.error, console.log)
// logs: [Object, Object, ..., Object]
Any inflight request can be cancelled like this :
runningRequest.cancel()
Task.runInWorker
Creates a task that run code inside a WebWorker and resolves/rejects with the result from the worker.
const workerTask = Task.runInWorker(
done => {
// Inside a new web worker!
const msg = 'Hello from a worker!'
// Call done to end worker and send result to main thread
done(msg)
}
)
workerTask.fork(console.error, console.log)
// logs : 'Hello from a worker!'
You can pass variables from You can even run tasks inside a WebWorker, taskorama is available in the worker scope :
const url = 'https://jsonplaceholder.typicode.com/photos'
const workerTask = Task.runInWorker(
done => {
// 'taskorama' is available in the worker!
taskorama.fetch(url)
.map(res => res.json())
.map(json => ({ action: 'UPDATE_PHOTO_LIST', payload: json }))
.run(result => {
// call 'done()' to terminate the worker and send a message to the main thread
done(result)
})
},
{ url: url, duration: 1000 } // passing two variables to the worker
)
workerTask.fork(console.error, console.log)
// logs : { action: 'UPDATE_PHOTO_LIST', payload: ... }
Task.wait
Creates a task that completes after a certain duration (first argument). It resolves with the value passed as second argument.
const timeoutTask = Task.wait(10000, "I'm done !")
const execTimeout = timeoutTask.fork(console.error, console.log)
// logs: "I'm done !" - after 10s
It can be cancelled like this :
execTimeout.cancel()
// the timeout is cancelled.
Task.all(array)
Creates a task that completes when all the tasks in the array are completed. It resolves with an array containing each value of each task of the array. If any of them rejects, the returned task rejects with the rejection reason.
If it is cancelled, it cancels all the tasks in the array as well.
const taskArray = [
Task.wait(2000,`one`),
Task.wait(3000,`two`),
Task.wait(1000,`three`),
Task.wait(4000,`four`),
]
const tasksAll = Task.all(taskArray)
tasksAll
.fork(console.error, console.log)
// logs: ['one', 'two', 'three', 'four'] - after 4s
Task.race
Creates a task that is fulfilled or rejected as soon as a task in the array is fulfilled or rejected.
If it is cancelled, it cancels all the tasks in the array as well.
const taskArray = [
Task.wait(2000,`one`),
Task.wait(3000,`two`),
Task.wait(1000,`three`),
Task.wait(4000,`four`),
]
const tasksRace = Task.race(taskArray)
tasksRace
.fork(console.error, console.log)
// logs: 'three' - after 1s
Task.sequence
Creates a task from an array of tasks, and run them in order. It resolves with an array containing the results of the execution of every task in the array in their initial order.
If it is cancelled, it cancels all the tasks in the array as well.
const taskArray = [
Task.wait(2000,`one`),
Task.wait(3000,`two`),
Task.wait(1000,`three`)
]
const tasksSequence = Task.sequence(taskArray)
tasksSequence
.fork(console.error, console.log)
// logs: ['one', 'two', 'three'] - after 6s
Task.parallel
Creates a task from an array of tasks, and run them concurrently. It resolves with an array containing the results of the execution of every task in the array in their order of completion.
If it is cancelled, it cancels all the tasks in the array as well.
const taskArray = [
Task.wait(2000,`one`),
Task.wait(3000,`two`),
Task.wait(1000,`three`)
]
const tasksParallel = Task.parallel(taskArray)
tasksParallel
.fork(console.error, console.log)
// logs: ['three', 'one', 'two'] - after 3s
Task.fromPromise
Creates a task from an existing Promise. Such a task cannot be cancelled because a Promise is not cancellable.
const p = Promise.resolve(2)
const taskFromPromise = Task.fromPromise(p)
taskFromPromise
.fork(console.error, console.log)
// logs: 2
Task.flippedArgs
Creates a task where the Task description has its arguments flipped (like promises)
const task = Task.flippedArgs(function(resolve, reject) {
resolve(42)
})
task
.fork(console.error, console.log)
// logs: 42
Task execution
When you execute a Task using .fork
or .run
, it returns a TaskExecution object which has the following methods :
.cancel()
Cancels the Task execution.
const afterSleep = () => console.log("I feel great!")
const sleep = Task.wait(1000)
const execution = sleep.run(afterSleep)
execution.cancel()
// The task is cancelled and `afterSleep` is never called.
.inspect()
Inspects the execution of a Task (this method is synchronous)
Pending
const afterSleep = () => console.log("I feel great!")
const sleep = Task.wait(3000, 'Wake up!')
const execution = sleep.run(afterSleep)
setTimeout(() => {
execution.inspect() // returns { status: 'pending', value: undefined }
}, 1000)
Cancelled
const afterSleep = () => console.log("I feel great!")
const sleep = Task.wait(1000)
const execution = sleep.run(afterSleep)
execution.cancel()
execution.inspect() // returns { status: 'cancelled', value: undefined }
Resolved
const resolvedTask = Task.of('Done!')
const execution = resolvedTask(console.log, console.log)
execution.inspect() // returns { status: 'resolved', value: 'Done!' }
Rejected
const rejectedTask = Task.reject('Boo')
const execution = rejectedTask.fork(console.log, console.log)
execution.inspect() // returns { status: 'rejected', reason: 'Boo' }
😉