or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

index.md
tile.json

tessl/npm-co

Generator-based async control flow library for Node.js and browsers using promises

Workspace
tessl
Visibility
Public
Created
Last updated
Describes
npmpkg:npm/co@4.6.x

To install, run

npx @tessl/cli install tessl/npm-co@4.6.0

index.mddocs/

co

co is a generator-based control flow library for Node.js and browsers that allows writing asynchronous code in a synchronous-looking style using JavaScript generators and promises. It serves as a stepping stone toward ES7 async/await syntax, providing a clean abstraction for complex asynchronous operations while maintaining backward compatibility.

Package Information

  • Package Name: co
  • Package Type: npm
  • Language: JavaScript
  • Installation: npm install co

Core Imports

const co = require('co');

ES6 modules:

import co from 'co';

Alternative access patterns:

const co = require('co');
// co is also available as:
co.default(); // Same as co()
co.co();      // Same as co()

Basic Usage

const co = require('co');

// Execute a generator function that yields promises
co(function* () {
  // Yield promises for async operations
  const result1 = yield Promise.resolve('Hello');
  const result2 = yield Promise.resolve('World');
  
  return `${result1} ${result2}`;
}).then(function(value) {
  console.log(value); // "Hello World"
}).catch(function(err) {
  console.error(err.stack);
});

// Wrap a generator function to return a promise-returning function
const asyncFunction = co.wrap(function* (name) {
  const greeting = yield Promise.resolve('Hello');
  return `${greeting}, ${name}!`;
});

asyncFunction('Alice').then(console.log); // "Hello, Alice!"

Capabilities

Generator Execution

Execute generator functions or generator instances and return promises.

/**
 * Execute the generator function or a generator and return a promise
 * @param {GeneratorFunction|Generator} gen - Generator function or generator instance
 * @param {...any} args - Additional arguments passed to generator function
 * @returns {Promise} Promise that resolves with the generator's return value
 */
function co(gen, ...args);

Usage Examples:

// Execute generator function
co(function* () {
  const data = yield fetch('/api/data').then(res => res.json());
  return data;
}).then(result => console.log(result));

// Execute with context and arguments
const result = co.call(context, function* (param1, param2) {
  return yield someAsyncOperation(param1, param2);
}, 'arg1', 'arg2');

// Execute generator instance
function* myGenerator() {
  return yield Promise.resolve('done');
}
co(myGenerator()).then(console.log);

Function Wrapping

Wrap generator functions to return promise-returning functions.

/**
 * Wrap the given generator function into a function that returns a promise
 * @param {GeneratorFunction} fn - Generator function to wrap
 * @returns {Function} Function that returns a promise when called
 */
co.wrap(fn);

Usage Examples:

// Create reusable async function
const fetchUser = co.wrap(function* (userId) {
  const user = yield fetch(`/api/users/${userId}`).then(res => res.json());
  const profile = yield fetch(`/api/profiles/${user.profileId}`).then(res => res.json());
  return { ...user, profile };
});

// Use the wrapped function
fetchUser(123).then(user => console.log(user));

// Access original generator function
console.log(fetchUser.__generatorFunction__); // Original generator function

Yieldable Types

co supports yielding various types of values that represent asynchronous operations:

Promises

Yield promise objects directly for async operations.

co(function* () {
  const result = yield Promise.resolve('value');
  const data = yield fetch('/api').then(res => res.json());
  return { result, data };
});

Thunks

Yield functions that accept a single callback parameter (legacy support).

co(function* () {
  // Thunk function
  const result = yield function(callback) {
    setTimeout(() => callback(null, 'delayed value'), 100);
  };
  return result;
});

Arrays (Parallel Execution)

Yield arrays of yieldable values for parallel execution using Promise.all().

co(function* () {
  // Execute promises in parallel
  const [user, posts, comments] = yield [
    fetch('/api/user').then(res => res.json()),
    fetch('/api/posts').then(res => res.json()),
    fetch('/api/comments').then(res => res.json())
  ];
  
  return { user, posts, comments };
});

Objects (Parallel Execution)

Yield objects with yieldable properties for parallel execution with labeled results.

co(function* () {
  // Execute promises in parallel with named results
  const results = yield {
    userData: fetch('/api/user').then(res => res.json()),
    settings: fetch('/api/settings').then(res => res.json()),
    notifications: fetch('/api/notifications').then(res => res.json())
  };
  
  // results = { userData: {...}, settings: {...}, notifications: [...] }
  return results;
});

Generators and Generator Functions

Yield other generators or generator functions for delegation.

function* fetchUserData(userId) {
  const user = yield fetch(`/api/users/${userId}`).then(res => res.json());
  return user;
}

co(function* () {
  // Yield generator function (executed with co)
  const user1 = yield fetchUserData(1);
  
  // Yield generator instance
  const user2 = yield fetchUserData(2);
  
  return [user1, user2];
});

Error Handling

co provides comprehensive error handling through promises and try/catch blocks:

// Promise-based error handling
co(function* () {
  return yield Promise.reject(new Error('Something went wrong'));
}).catch(err => {
  console.error('Caught error:', err.message);
});

// Generator try/catch error handling
co(function* () {
  try {
    const result = yield Promise.reject(new Error('API Error'));
  } catch (err) {
    console.error('Handled in generator:', err.message);
    return 'fallback value';
  }
});

// Invalid yieldable type error
co(function* () {
  try {
    // This will throw a TypeError
    const result = yield "invalid yieldable";
  } catch (err) {
    console.error(err.message);
    // "You may only yield a function, promise, generator, array, or object, but the following object was passed: "invalid yieldable""
  }
});

Platform Compatibility

  • Node.js: Requires Node.js 0.12.0+ or io.js 1.0.0+
  • Generators: Requires --harmony flag for Node.js versions < 4.0
  • Promises: Requires native Promise support or polyfill
  • Browser: Supported via browserify build

Advanced Patterns

Nested Yieldables

co supports deeply nested structures of yieldable objects:

co(function* () {
  const result = yield {
    users: [
      fetch('/api/users/1').then(res => res.json()),
      fetch('/api/users/2').then(res => res.json())
    ],
    metadata: {
      count: fetch('/api/users/count').then(res => res.json()),
      lastUpdated: Promise.resolve(new Date())
    }
  };
  
  return result;
});

Context Preservation

co preserves the this context throughout generator execution:

const api = {
  baseUrl: 'https://api.example.com',
  
  fetchData: co.wrap(function* (endpoint) {
    const url = `${this.baseUrl}${endpoint}`; // 'this' is preserved
    return yield fetch(url).then(res => res.json());
  })
};

api.fetchData('/users').then(console.log);