or

Combines two tasks such that the resulting task assimilates the result of the first one to resolve.

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

value(that)
forall e, v:
  (Task e v).(Task e v) => Task e v

Documentation

Combines two tasks such that the resulting task assimilates the result of the first one to resolve.

Note that once a task finishes, the other task is cancelled. If the combined task is cancelled, both tasks are also cancelled.

As a convenience for combining a large or unknown amount of tasks, the waitAny() function in the concurrency/task module preceives an array of Tasks to "or" together.

Example:

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

const delay = (ms) => task(
  resolver => {
    const timerId = setTimeout(() => resolver.resolve(ms), ms);
    resolver.cleanup(() => {
      clearTimeout(timerId);
    });
  }
);

const timeout = (ms) => task(
  resolver => {
    const timerId = setTimeout(() => resolver.reject(ms), ms);
    resolver.cleanup(() => {
      clearTimeout(timerId);
    });
  }
);

const result = await delay(20).or(timeout(300))
                 .run().promise();
$ASSERT(result == 20);

const result2 = await delay(200).or(timeout(100))
                  .run().promise().catch(e => `timeout ${e}`);
$ASSERT(result2 == 'timeout 100');

Properties

Source Code

Defined in source/concurrency/task/_task.js at line 20, column 0
or(that) {
    return new Task(resolver => {
      let thisExecution = this.run();   // eslint-disable-line prefer-const
      let thatExecution = that.run();   // eslint-disable-line prefer-const
      let done = false;

      resolver.onCancelled(() => {
        thisExecution.cancel();
        thatExecution.cancel();
      });

      const guard = (fn, execution) => (value) => {
        if (!done) {
          done = true;
          execution.cancel();
          fn(value);
        }
      };

      thisExecution.listen({
        onRejected:  guard(resolver.reject, thatExecution),
        onCancelled: guard(resolver.cancel, thatExecution),
        onResolved:  guard(resolver.resolve, thatExecution)
      });

      thatExecution.listen({
        onRejected:  guard(resolver.reject, thisExecution),
        onCancelled: guard(resolver.cancel, thisExecution),
        onResolved:  guard(resolver.resolve, thisExecution)
      });
    });
  }
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/)