task

Constructs a Task and associates a computation to it. The computation is executed every time the Task is ran, and should provide the result of the task: a success or failure along with its value.

This feature is experimental!

This API is still experimental, so it may change or be removed in future versions. You should not rely on it for production applications.

Signature

task(computation)
forall value, reason:
  (
    ({
       resolve: (value) => Void,
       reject: (reason) => Void,
       cancel: () => Void,
       cleanup: (() => Void) => Void,
       onCancelled: (() => Void) => Void,
       get isCancelled: Boolean
     }) => Void
  ) => Task reason value

Documentation

Constructs a Task and associates a computation to it. The computation is executed every time the Task is ran, and should provide the result of the task: a success or failure along with its value.

A computation is required. For task, this is a function that receives one argument, the resolver, and does some work that may be asynchronous. Once done, the computation uses the resolver to resolve() a task succesfully, or reject() it with an error.

Asynchronous computations that allocate some external resource (for example, starting an HTTP request) can provide a cleanup function. The cleanup function will be called with the resources returned, and will have the chance of disposing of them properly once the Task is finished, either properly, as a success or rejection, or eagerly, as a cancellation.

Optionally, a Task may provide an onCancelled function that will be called if the Task is cancelled, before the cleanup.

Example:

const { task } = require('folktale/concurrency/task');

A simple, successful task:

const hello = task(resolver => resolver.resolve('hello'));

const result1 = await hello.run().promise();
$ASSERT(result1 == 'hello');

A simple, failed task:

const nope = task(resolver => resolver.reject('hello'));

try {
  await nope.run().promise();
  throw 'never happens';
} catch (error) {
  $ASSERT(error == 'hello');
}

An asynchronous task that allocates and frees resources:

const delay50 = task(
  resolver => {
    const timerId = setTimeout(() => resolver.resolve('yay'), 50);
    resolver.cleanup(() => {
      clearTimeout(timerId);
    });
  }
);

const result2 = await delay50.run().promise();
$ASSERT(result2 == 'yay');

A task with a cancellation handler:

let resolved = false;
const cancelMe = task(
  resolver => {
    const timerId = setTimeout(() => {
      resolved = true;
      resolver.resolve('yay');
    }, 50);

    resolver.cleanup(() => {
      clearTimeout(timerId);
    });

    resolver.onCancelled(() => {
      /* task was cancelled */
    });
  }
);

try {
  const execution = cancelMe.run();
  execution.cancel();
  const result3 = await execution.promise();
  throw 'never happens';
} catch (error) {
  $ASSERT(resolved == false);
}

Properties

Source Code

Defined in source/concurrency/task/task.js at line 29, column 0
(computation) =>
  new Task(computation)
Stability
experimental
Licence
MIT
Module
folktale/concurrency/task/task
Authors
Copyright
(c) 2013-2017 Quildreen Motta, and CONTRIBUTORS
Authors
  • Quildreen Motta
Maintainers
  • Quildreen Motta <queen@robotlolita.me> (http://robotlolita.me/)