or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

fiber-core.mdfuture.mdindex.md
tile.json

future.mddocs/

Future Abstractions

Promise-like abstraction that wraps fiber operations in a more familiar async/await-style interface. The Future API is designed to make it easy to move between classic callback-style code and fiber-aware waiting code, making it ideal for converting Node.js callback-based APIs to synchronous-style code.

Capabilities

Future Constructor

Creates a new Future object for async operations.

/**
 * Future object, instantiated with the new operator.
 */
function Future() {}

Usage Examples:

var Future = require('fibers/future');

// Create and manually resolve a future
var future = new Future();
setTimeout(function() {
  future.return('resolved value');
}, 1000);

// In a fiber context, wait for resolution
Future.task(function() {
  var result = future.wait(); // Blocks fiber until resolved
  console.log(result); // 'resolved value'
}).detach();

Function Future Extension

Converts functions to return futures when called.

/**
 * Returns a future-function which, when run, starts running the target
 * function and returns a future for the result.
 * 
 * @param {boolean} detach - Optional. If true, automatically calls detach() on the returned future
 * @returns {Function} Function that returns futures when called
 * 
 * Example usage: 
 * var funcy = function(arg) {
 *   return arg+1;
 * }.future();
 * 
 * funcy(1).wait(); // returns 2
 * 
 * // With detach parameter - runs in background without need to wait
 * var backgroundTask = function() {
 *   console.log('Background work');
 * }.future(true);  // Auto-detaches
 * 
 * backgroundTask(); // Runs in background, doesn't need .wait()
 */
Function.prototype.future = function(detach) { /* ... */ }

Usage Examples:

// Convert function to return futures
var asyncAdd = function(a, b) {
  return a + b;
}.future();

Future.task(function() {
  var result = asyncAdd(5, 3).wait(); // Returns: 8
  console.log(result);
}).detach();

Task Execution

Runs functions in fiber context and returns futures to their return values.

/**
 * Invoke a function that will be run in its own fiber context and return a future to its return
 * value.
 *
 * @param {Function} fn - Function to run in fiber context
 * @returns {Future} Future resolving to function's return value
 * 
 * Example:
 * Future.task(function() {
 *   // You can safely `wait` on stuff here
 * }).detach();
 */
Future.task = function(fn) { /* ... */ }

Usage Examples:

// Simple task execution
Future.task(function() {
  console.log('Running in fiber');
  return 'task result';
}).resolve(function(err, val) {
  if (err) throw err;
  console.log(val); // 'task result'
});

Function Wrapping

Wraps node-style async functions to return futures instead of using callbacks.

/**
 * Wrap a node-style async function to return a future in place of using a callback.
 * 
 * @param {Function|Object} fn - The function or object to wrap
 * @param {boolean} multi - Indicates callback returns more than 1 argument after `err`
 * @param {string} suffix - Appends string to every wrapped method name (default: 'Future')
 * @param {boolean} stop - Internal parameter to prevent recursive wrapping
 * @returns {Function|Object} Future-returning function or wrapped object
 * 
 * Example usage: Future.wrap(asyncFunction)(arg1).wait()
 */
Future.wrap = function(fn, multi, suffix, stop) { /* ... */ }

Usage Examples:

var fs = Future.wrap(require('fs'));

Future.task(function() {
  // Synchronous-style file operations
  var files = fs.readdirFuture('.').wait();
  console.log('Found ' + files.length + ' files');
  
  var content = fs.readFileFuture('package.json').wait();
  console.log('Package.json content:', content.toString());
}).detach();

Multiple Future Waiting

Waits for multiple futures to resolve.

/**
 * Wait on a series of futures and then return. If the futures throw an exception this function
 * /won't/ throw it back. You can get the value of the future by calling get() on it directly. If
 * you want to wait on a single future you're better off calling future.wait() on the instance.
 * 
 * Example usage: Future.wait(aFuture, anotherFuture)
 */
Future.wait = function(/* ... */) { /* ... */ }

Usage Examples:

Future.task(function() {
  var fs = Future.wrap(require('fs'));
  
  // Start multiple async operations
  var file1 = fs.readFileFuture('file1.txt');
  var file2 = fs.readFileFuture('file2.txt');
  var file3 = fs.readFileFuture('file3.txt');
  
  // Wait for all to complete
  Future.wait(file1, file2, file3);
  
  // Get results
  console.log('File 1:', file1.get().toString());
  console.log('File 2:', file2.get().toString());
  console.log('File 3:', file3.get().toString());
}).detach();

Promise Interoperability

Converts between Futures and ES6 Promises.

/**
 * Returns a Future that waits on an ES6 Promise.
 * @param {Promise} promise - ES6 Promise to convert
 * @returns {Future} Future that resolves when promise resolves
 */
Future.fromPromise = function(promise) { /* ... */ }

Future Instance Methods

Value Retrieval

/**
 * Return the value of this future. If the future hasn't resolved yet this will throw an error.
 * @returns {*} The resolved value
 * @throws {Error} If future is not resolved or was rejected
 */
Future.prototype.get = function() { /* ... */ }

Future Resolution

/**
 * Mark this future as returned. All pending callbacks will be invoked immediately.
 * 
 * @param {*} value - The value to return when get() or wait() is called
 * 
 * Example usage: aFuture.return(value)
 */
Future.prototype.return = function(value) { /* ... */ }

/**
 * Throw from this future as returned. All pending callbacks will be invoked immediately.
 * Note that execution will continue normally after running this method, 
 * so make sure you exit appropriately after running throw()
 * 
 * @param {Error} error - The error to throw when get() or wait() is called
 * 
 * Example usage: aFuture.throw(new Error("Something borked"))
 */
Future.prototype.throw = function(error) { /* ... */ }

Future State Management

/**
 * Returns whether or not this future has resolved yet.
 * @returns {boolean} True if resolved, false otherwise
 */
Future.prototype.isResolved = function() { /* ... */ }

/**
 * "detach" this future. Basically this is useful if you want to run a task in a future, you
 * aren't interested in its return value, but if it throws you don't want the exception to be
 * lost. If this fiber throws, an exception will be thrown to the event loop and node will
 * probably fall down.
 */
Future.prototype.detach = function() { /* ... */ }

Callback Integration

/**
 * Returns a node-style function which will mark this future as resolved when called.
 * 
 * @returns {Function} Node-style callback (err, val) => void
 * 
 * Example usage: 
 *   var errback = aFuture.resolver();
 *   asyncFunction(arg1, arg2, etc, errback)
 *   var result = aFuture.wait();
 */
Future.prototype.resolver = function() { /* ... */ }

/**
 * Waits for this future to resolve and then invokes a callback.
 *
 * If only one argument is passed it is a standard function(err, val){} errback.
 *
 * If two arguments are passed, the first argument is a future which will be thrown to in the case
 * of error, and the second is a function(val){} callback.
 * 
 * @param {Function|Future} arg1 - Errback function or future for error propagation
 * @param {Function} arg2 - Success callback (if first arg is a future)
 * @returns {Future} This future for chaining
 */
Future.prototype.resolve = function(arg1, arg2) { /* ... */ }

Future Propagation

/**
 * Propogate results to another future.
 * 
 * @param {Future} future - Target future to propagate results to
 * 
 * Example usage: future1.proxy(future2) // future2 gets automatically resolved with however future1 resolves
 */
Future.prototype.proxy = function(future) { /* ... */ }

/**
 * Propogate only errors to an another future or array of futures.
 * 
 * @param {Future|Future[]} futures - Target future(s) for error propagation
 * @returns {Future} This future for chaining
 */
Future.prototype.proxyErrors = function(futures) { /* ... */ }

Promise Conversion

/**
 * Returns an ES6 Promise
 * @returns {Promise} ES6 Promise that resolves when this future resolves
 */
Future.prototype.promise = function() { /* ... */ }

Synchronous Waiting

/**
 * Differs from its functional counterpart in that it actually resolves the future. Thus if the
 * future threw, future.wait() will throw.
 * @returns {*} The resolved value
 * @throws {Error} If future was rejected
 */
Future.prototype.wait = function() { /* ... */ }

Advanced Usage Examples

File System Operations

var Future = require('fibers/future');
var fs = Future.wrap(require('fs'));

Future.task(function() {
  // Get list of files
  var fileNames = fs.readdirFuture('.').wait();
  console.log('Found ' + fileNames.length + ' files');

  // Stat each file in parallel
  var stats = [];
  for (var ii = 0; ii < fileNames.length; ++ii) {
    stats.push(fs.statFuture(fileNames[ii]));
  }
  
  // Wait for all stats to complete
  stats.map(function(f) { f.wait(); });

  // Print file sizes
  for (var ii = 0; ii < fileNames.length; ++ii) {
    console.log(fileNames[ii] + ': ' + stats[ii].get().size);
  }
}).detach();

Custom Async Operations

// Create custom async operation using Future
function sleep(ms) {
  var future = new Future();
  setTimeout(function() {
    future.return();
  }, ms);
  return future;
}

// Use with automatic fiber execution
var calcTimerDelta = function(ms) {
  var start = new Date();
  sleep(ms).wait();
  return new Date() - start;
}.future();

// Get result with callback
calcTimerDelta(2000).resolve(function(err, val) {
  console.log('Set timer for 2000ms, waited ' + val + 'ms');
});