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

promise-chains.mddocs/

Promise Chain Methods

Core promise instance methods for building promise chains with transformations, error handling, and chain termination.

Capabilities

Then Method

The fundamental promise chaining method for handling fulfillment and rejection.

/**
 * Standard promise then with optional timing estimate
 * @param fulfilled - Callback for successful resolution
 * @param rejected - Optional callback for rejection handling
 * @param ms - Optional timing estimate in milliseconds
 * @returns New promise for the callback result
 */
promise.then(fulfilled, rejected, ms);

Usage Examples:

const Q = require("q");

// Basic then usage
Q.resolve("Hello")
  .then(value => value.toUpperCase())
  .then(value => console.log(value)) // "HELLO"
  .catch(error => console.error(error));

// With both success and error handlers
fetchUser(123)
  .then(
    user => {
      console.log("User loaded:", user.name);
      return user.email;
    },
    error => {
      console.error("Failed to load user:", error.message);
      return "default@example.com";
    }
  )
  .then(email => sendWelcomeEmail(email));

// With timing estimate
Q.resolve(complexData)
  .then(data => {
    return processComplexData(data);
  }, undefined, 5000) // Estimate 5 seconds for processing
  .then(result => console.log("Processing complete:", result));

// Chaining multiple transformations
fetchUserData()
  .then(data => validateData(data))
  .then(validData => enrichData(validData))
  .then(enrichedData => saveToDatabase(enrichedData))
  .then(savedData => notifyUser(savedData.id))
  .catch(error => handleError(error));

Catch Method

Specialized error handling method for promise chains.

/**
 * Handles rejections (alias for then(undefined, rejected))
 * @param rejected - Callback for rejection handling
 * @returns New promise for the error handler result
 */
promise.catch(rejected);

Usage Examples:

const Q = require("q");

// Basic error handling
Q.reject(new Error("Something went wrong"))
  .catch(error => {
    console.error("Caught error:", error.message);
    return "default value";
  })
  .then(value => console.log("Result:", value));

// Specific error handling
fetchDataFromAPI()
  .catch(error => {
    if (error.code === "NETWORK_ERROR") {
      console.log("Network issue, trying cache...");
      return fetchFromCache();
    } else if (error.code === "AUTH_ERROR") {
      console.log("Authentication failed, redirecting...");
      redirectToLogin();
      throw error;
    } else {
      console.error("Unexpected error:", error);
      throw error;
    }
  })
  .then(data => processData(data))
  .catch(error => showErrorToUser(error.message));

// Error recovery patterns
function robustDataFetch(url) {
  return fetch(url)
    .catch(error => {
      console.log("Primary fetch failed, trying backup...");
      return fetch(url.replace("api", "backup-api"));
    })
    .catch(error => {
      console.log("Backup fetch failed, using cached data...");
      return getCachedData(url);
    })
    .catch(error => {
      console.log("Cache miss, using default data...");
      return getDefaultData();
    });
}

Done Method

Terminates promise chains and ensures uncaught errors are thrown.

/**
 * Terminates chain, forces exceptions to be thrown
 * @param fulfilled - Optional callback for successful resolution
 * @param rejected - Optional callback for rejection handling
 * @returns void (does not return a promise)
 */
promise.done(fulfilled, rejected);

Usage Examples:

const Q = require("q");

// Basic chain termination
fetchUserData()
  .then(data => processData(data))
  .then(result => updateUI(result))
  .catch(error => showErrorMessage(error))
  .done(); // Ensures any uncaught errors are thrown

// With success handler
Q.resolve("important data")
  .then(data => criticalOperation(data))
  .done(
    result => console.log("Operation succeeded:", result),
    error => console.error("Critical operation failed:", error)
  );

// Ensuring error propagation
function criticalProcess() {
  return loadConfiguration()
    .then(config => validateConfiguration(config))
    .then(validConfig => initializeSystem(validConfig))
    .catch(error => {
      console.error("System initialization failed:", error);
      process.exit(1); // Critical failure
    })
    .done(); // Ensure any programming errors are thrown
}

// Fire-and-forget operations
function backgroundTask() {
  cleanupTempFiles()
    .then(() => updateMetrics())
    .then(() => sendHeartbeat())
    .catch(error => logError("Background task failed:", error))
    .done(); // Don't return promise, just ensure completion
}

Finally Method (inherited from flow-control)

Executes cleanup code regardless of promise resolution or rejection.

/**
 * Executes callback regardless of fulfillment or rejection
 * @param callback - Function to execute for cleanup
 * @param ms - Optional timing estimate
 * @returns Promise that preserves original result
 */
promise.finally(callback, ms);

Usage Examples:

const Q = require("q");

// Database connection cleanup
function queryDatabase(sql) {
  let connection;
  
  return connectToDatabase()
    .then(conn => {
      connection = conn;
      return connection.query(sql);
    })
    .finally(() => {
      if (connection) {
        connection.close();
        console.log("Database connection closed");
      }
    });
}

// Loading state management
function performLongOperation() {
  showLoadingSpinner();
  
  return longRunningTask()
    .then(result => {
      showSuccessMessage("Operation completed");
      return result;
    })
    .catch(error => {
      showErrorMessage("Operation failed: " + error.message);
      throw error;
    })
    .finally(() => {
      hideLoadingSpinner();
    });
}

Value Transformation Methods

Methods for transforming promise values regardless of the original outcome.

/**
 * Resolves to specific value regardless of original result
 * @param value - Value to resolve with
 * @returns Promise that resolves to the specified value
 */
promise.thenResolve(value);

/**
 * Rejects with specific error regardless of original result
 * @param error - Error to reject with
 * @returns Promise that rejects with the specified error
 */
promise.thenReject(error);

Usage Examples:

const Q = require("q");

// Transform any outcome to success
checkPermissions()
  .thenResolve("access granted")
  .then(message => console.log(message));

// Transform any outcome to failure
deprecatedFunction()
  .thenReject(new Error("This function is deprecated"))
  .catch(error => console.error(error.message));

// Conditional transformation
function processWithDefault(promise, defaultValue) {
  return promise
    .catch(error => {
      console.log("Operation failed, using default");
      return Q.resolve().thenResolve(defaultValue);
    });
}

// Status code transformation
function apiCall(endpoint) {
  return httpRequest(endpoint)
    .then(response => {
      if (response.status === 200) {
        return response.data;
      } else {
        return Q.resolve().thenReject(
          new Error(`API error: ${response.status}`)
        );
      }
    });
}

Chain Composition Patterns

Sequential Processing

const Q = require("q");

// Process items sequentially
function processSequentially(items, processor) {
  return items.reduce((promise, item) => {
    return promise.then(results => {
      return processor(item).then(result => {
        results.push(result);
        return results;
      });
    });
  }, Q.resolve([]));
}

// Usage
const items = [1, 2, 3, 4, 5];
processSequentially(items, num => Q.delay(num * 2, 100))
  .then(results => console.log("Sequential results:", results))
  .done();

Conditional Chaining

const Q = require("q");

// Conditional promise chains
function conditionalProcess(data, condition) {
  return Q.resolve(data)
    .then(data => {
      if (condition(data)) {
        return expensiveOperation(data);
      } else {
        return quickOperation(data);
      }
    })
    .then(result => finalizeResult(result));
}

// Branch and merge pattern
function branchAndMerge(input) {
  return Q.resolve(input)
    .then(data => {
      if (data.type === "premium") {
        return premiumProcessing(data)
          .then(result => ({ ...result, tier: "premium" }));
      } else {
        return standardProcessing(data)
          .then(result => ({ ...result, tier: "standard" }));
      }
    })
    .then(result => applyCommonPostProcessing(result));
}

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