CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-q

A comprehensive promise library implementing CommonJS Promises/A,B,D specifications for JavaScript

Pending

Quality

Pending

Does it follow best practices?

Impact

Pending

No eval scenarios have been run

Overview
Eval results
Files

functional.mddocs/

Functional Programming

Function wrappers and utilities for integrating promises with functional programming patterns, including async/generator support and promise-based functional composition.

Capabilities

Function Wrapping

Utilities for wrapping regular functions to work seamlessly with promises.

/**
 * Wraps function to return promises
 * @param wrapped - Function to wrap for promise compatibility
 * @returns Function that returns promises
 */
function Q.function(wrapped);

/**
 * Decorator ensuring promise arguments and return value
 * @param callback - Function to wrap with promise handling
 * @returns Function that handles promise arguments and returns promises
 */
function Q.promised(callback);

Usage Examples:

const Q = require("q");

// Wrap regular function to return promises
const syncAdd = (a, b) => a + b;
const asyncAdd = Q.function(syncAdd);

asyncAdd(5, 3)
  .then(result => console.log("Result:", result)) // 8
  .catch(error => console.error(error));

// Wrap function that may throw
const riskyFunction = (data) => {
  if (!data) throw new Error("No data provided");
  return data.toUpperCase();
};

const safeRiskyFunction = Q.function(riskyFunction);

safeRiskyFunction("hello")
  .then(result => console.log(result)) // "HELLO"
  .catch(error => console.error(error));

safeRiskyFunction(null)
  .catch(error => console.error("Caught:", error.message));

// Q.promised for promise-aware functions
const promisedProcessor = Q.promised((data, config) => {
  // Both data and config can be promises or values
  return `Processed: ${data} with ${config.mode}`;
});

// Use with mixed promise/value arguments
promisedProcessor(
  Q.delay("user data", 100),
  { mode: "strict" }
).then(result => console.log(result));

// Chain with other promise operations
const processUser = Q.promised((user, settings) => {
  return {
    id: user.id,
    name: user.name.toUpperCase(),
    theme: settings.theme
  };
});

fetchUser(123)
  .then(user => processUser(user, getSettings()))
  .then(processedUser => console.log(processedUser));

Value Comparison and Joining

Functions for comparing and joining promise values.

/**
 * Resolves to value if both promises fulfill to same value
 * @param x - First promise or value
 * @param y - Second promise or value
 * @returns Promise that resolves if both values are equal
 */
function Q.join(x, y);

Usage Examples:

const Q = require("q");

// Join with identical values
Q.join(Q.resolve("same"), Q.resolve("same"))
  .then(value => console.log("Both resolved to:", value))
  .catch(() => console.log("Values were different"));

// Join with different values (will reject)
Q.join(Q.resolve("first"), Q.resolve("second"))
  .then(value => console.log("Unexpected success:", value))
  .catch(() => console.log("Values were different, as expected"));

// Real-world example: verify consistency
function verifyDataConsistency(primarySource, backupSource) {
  return Q.join(
    fetchDataFromPrimary(primarySource),
    fetchDataFromBackup(backupSource)
  ).then(consistentData => {
    console.log("Data is consistent:", consistentData);
    return consistentData;
  }).catch(error => {
    console.warn("Data inconsistency detected, investigating...");
    return investigateInconsistency(primarySource, backupSource);
  });
}

// Permission verification
function verifyUserPermissions(userId, requiredRole) {
  return Q.join(
    fetchUserRole(userId),
    Q.resolve(requiredRole)
  ).then(role => {
    console.log(`User has required role: ${role}`);
    return true;
  }).catch(() => {
    console.log("User does not have required permissions");
    return false;
  });
}

Async/Generator Support

Advanced support for ES6 generator functions and async patterns.

/**
 * Decorator for generator functions to work with promises
 * @param makeGenerator - Generator function that yields promises
 * @returns Function that returns promise for generator completion
 */
function Q.async(makeGenerator);

/**
 * Runs async generator immediately with error handling
 * @param makeGenerator - Generator function to execute
 * @returns Promise for generator completion result
 */
function Q.spawn(makeGenerator);

Usage Examples:

const Q = require("q");

// Q.async for reusable async generators
const fetchUserProfile = Q.async(function* (userId) {
  const user = yield fetchUser(userId);
  const preferences = yield fetchUserPreferences(userId);
  const activity = yield fetchUserActivity(userId);
  
  return {
    user,
    preferences,
    activity,
    lastUpdated: new Date()
  };
});

// Use the async function
fetchUserProfile(123)
  .then(profile => console.log("Complete profile:", profile))
  .catch(error => console.error("Profile fetch failed:", error));

// Q.spawn for immediate execution
Q.spawn(function* () {
  try {
    console.log("Starting data migration...");
    
    const sourceData = yield connectToSourceDatabase();
    const targetDb = yield connectToTargetDatabase();
    
    const users = yield sourceData.query("SELECT * FROM users");
    console.log(`Migrating ${users.length} users...`);
    
    for (let user of users) {
      yield targetDb.insert("users", transformUser(user));
      console.log(`Migrated user: ${user.name}`);
    }
    
    yield sourceData.close();
    yield targetDb.close();
    
    console.log("Migration completed successfully");
  } catch (error) {
    console.error("Migration failed:", error);
    throw error;
  }
}).done();

// Complex async workflow
const processOrderWorkflow = Q.async(function* (orderId) {
  const order = yield fetchOrder(orderId);
  
  // Validate order
  const validation = yield validateOrder(order);
  if (!validation.valid) {
    throw new Error(`Order validation failed: ${validation.errors.join(", ")}`);
  }
  
  // Process payment
  const paymentResult = yield processPayment(order.payment);
  if (!paymentResult.success) {
    throw new Error(`Payment failed: ${paymentResult.error}`);
  }
  
  // Update inventory
  yield updateInventory(order.items);
  
  // Schedule shipping
  const shipping = yield scheduleShipping(order);
  
  // Send confirmations
  yield Q.all([
    sendCustomerConfirmation(order.customerId, order),
    sendMerchantNotification(order.merchantId, order),
    logOrderProcessing(orderId, "completed")
  ]);
  
  return {
    orderId,
    status: "processed",
    paymentId: paymentResult.transactionId,
    shippingId: shipping.trackingNumber,
    processedAt: new Date()
  };
});

// Usage
processOrderWorkflow("order-123")
  .then(result => console.log("Order processed:", result))
  .catch(error => console.error("Order processing failed:", error));

Higher-Order Promise Functions

Advanced functional programming patterns with promises.

const Q = require("q");

// Promise-based map function
function promiseMap(array, mapper) {
  const mappedPromises = array.map(item => Q.resolve(item).then(mapper));
  return Q.all(mappedPromises);
}

// Promise-based filter function
function promiseFilter(array, predicate) {
  const filterPromises = array.map(item => 
    Q.resolve(item).then(predicate).then(passed => ({ item, passed }))
  );
  
  return Q.all(filterPromises).then(results => 
    results.filter(result => result.passed).map(result => result.item)
  );
}

// Promise-based reduce function
function promiseReduce(array, reducer, initialValue) {
  return array.reduce((promise, item) => {
    return promise.then(accumulator => 
      Q.all([accumulator, item]).spread(reducer)
    );
  }, Q.resolve(initialValue));
}

// Usage examples
const numbers = [1, 2, 3, 4, 5];

// Map with async operation
promiseMap(numbers, num => Q.delay(num * 2, 50))
  .then(doubled => console.log("Doubled:", doubled));

// Filter with async predicate
promiseFilter(numbers, num => Q.delay(num > 3, 10))
  .then(filtered => console.log("Filtered:", filtered));

// Reduce with async reducer
promiseReduce(numbers, (acc, num) => Q.delay(acc + num, 10), 0)
  .then(sum => console.log("Sum:", sum));

Composition Utilities

Utilities for composing promise-based functions.

const Q = require("q");

// Function composition for promises
function composeAsync(...functions) {
  return function(input) {
    return functions.reduce((promise, fn) => {
      return promise.then(fn);
    }, Q.resolve(input));
  };
}

// Pipeline for sequential processing
function pipeline(...stages) {
  return function(input) {
    return stages.reduce((promise, stage) => {
      return promise.then(stage);
    }, Q.resolve(input));
  };
}

// Usage
const processData = composeAsync(
  data => Q.delay(data.trim(), 10),
  data => Q.delay(data.toUpperCase(), 10),
  data => Q.delay(`Processed: ${data}`, 10)
);

processData("  hello world  ")
  .then(result => console.log(result)); // "Processed: HELLO WORLD"

// Data processing pipeline
const dataPipeline = pipeline(
  data => validateInput(data),
  data => enrichWithMetadata(data),
  data => applyBusinessRules(data),
  data => formatForOutput(data)
);

dataPipeline(rawData)
  .then(processedData => console.log("Pipeline result:", processedData))
  .catch(error => console.error("Pipeline failed:", error));

Install with Tessl CLI

npx tessl i tessl/npm-q

docs

advanced.md

collections.md

core-promises.md

flow-control.md

functional.md

index.md

nodejs.md

promise-chains.md

property-access.md

queue.md

state-inspection.md

tile.json