Replace API Memory with Logical Concepts
The design philosophy of promise-logic is: Developers should focus on business logic, not on details of Promise APIs.
Traditional Promise combinations (such as Promise.all, Promise.race) have naming and semantics that are not intuitive enough, especially in complex asynchronous scenarios where code readability rapidly declines.
promise-logic abstracts asynchronous combinations into logical operations like and, or, xor through the concept of Logic Gates, making code semantically clear and self-explanatory.
import { PromiseLogic } from 'promise-logic';
// Order processing flow
async function createOrder() {
try {
// Execute payment and inventory operations (both must succeed)
const [
[paymentResult, inventoryResult], // Payment and inventory operation results
logistics, // Logistics operation result
coupon // Coupon operation result
] = await PromiseLogic.and([
// Payment and inventory operations must both succeed
PromiseLogic.and([paymentAPI(), inventoryAPI()]),
// At least one logistics operation must succeed
PromiseLogic.or([oneLogisticsAPI(), twoLogisticsAPI()], {
errorType: 'LOGISTICS_ERROR', // Custom logistics error type
}),
// At least one coupon must be available
PromiseLogic.or([couponAPI1(), couponAPI2()], {
errorType: 'COUPON_ERROR', // Custom coupon error type
})
], {
errorType: 'ORDER_ERROR', // Custom order error type
errorMessage: 'Order creation failed' // Custom order error message
});
// Order creation successful, return payment result, inventory result, logistics result and coupon result
return {
payment: paymentResult,
inventory: inventoryResult,
logistics: logistics,
coupon: coupon,
status: 'success'
};
} catch (error) {
// Analyze error type
switch (error.type) {
case 'ORDER_ERROR':
return {
status: 'error',
errorType: 'order_error',
message: 'Order creation failed',
details: error
};
case 'AND_ERROR':
return {
status: 'error',
errorType: 'payment_or_inventory_failed',
message: 'Payment or inventory operation failed',
details: error
};
case 'LOGISTICS_ERROR':
return {
status: 'error',
errorType: 'logistics_unavailable',
message: 'All logistics services are unavailable',
details: error
};
case 'COUPON_ERROR':
return {
status: 'error',
errorType: 'coupon_error',
message: 'All coupons are unavailable',
details: error
};
default:
return {
status: 'error',
errorType: 'default_error',
message: 'Unknown error occurred during order creation',
details: error
};
}
}
}As you can see, the code structure is completely consistent with business rules. Code is documentation, and logic is self-explanatory.
and: All tasks must succeed (equivalent toPromise.all)or: At least one task succeeds (equivalent toPromise.any)xor: Exactly one task succeedsnand: Not all tasks succeed (at least one fails)nor: All tasks fail (no task succeeds)xnor: All tasks succeed or all fail (same state)not: Inverts the result of a single Promisemajority: Most tasks succeed
Only depends on native Promise, no additional runtime dependencies.
All logic gates have undergone rigorous unit testing to ensure behavior meets expectations.
PromiseLogicErrorunified error typeerror.typedistinguishes specific logical errors (e.g.,'XOR_ERROR')- Supports custom error types and messages
maxTimer: Adds timeout functionality to any Promise operation (unit: milliseconds)- Supports custom timeout error messages
Note: After timeout, it immediately interrupts the execution of the current Promise chain and jumps to error handling, but does not cancel underlying asynchronous operations that have already started (such as network requests, file read/write, etc.).
allFulfilled: Returns all successful results in order, immediately tries to return when there are successful resultsallRejected: Returns all failed results in order, immediately tries to return when there are failed resultsallSettled: Returns all results (both successful and failed)
npm install promise-logicimport { PromiseLogic } from 'promise-logic';
// Execute XOR logic: exactly one success
PromiseLogic.xor([
biometricAuth(), // Biometric authentication
hardwareKeyAuth() // Hardware key authentication
])
.then((result) => {
console.log('Successfully authenticated:', result);
})
.catch((error) => {
if (error.type === 'XOR_ERROR') {
console.error('Conflict between biometric and hardware key authentication');
} else {
console.error('Authentication error:', error);
}
});import { PromiseLogic } from 'promise-logic';
const services = [
fetch('https://api.node1.com/vote'),
fetch('https://api.node2.com/vote'),
fetch('https://api.node3.com/vote')
];
// Custom threshold 0.6 (60%)
PromiseLogic.majority(services, { max: 0.6 })
.then((results) => {
console.log('Custom threshold met, successful results:', results);
})
.catch((error) => {
console.error('Custom threshold not met:', error);
});import { PromiseLogic } from 'promise-logic';
// Execute operation with custom timeout error message
PromiseLogic.and([
Promise.resolve(1),
new Promise((resolve) => setTimeout(resolve, 3000)), // 3 second operation
Promise.resolve(3)
])
.maxTimer(2000, 'Custom timeout error: operation did not complete within 2000ms') // 2 second timeout
.then((result) => {
console.log('Operation completed within timeout:', result);
})
.catch((error) => {
console.error('Operation timed out:', error.message);
});import { PromiseLogic } from 'promise-logic';
const operations = [
Promise.resolve('success1'),
Promise.reject('error1'),
Promise.resolve('success2'),
Promise.reject('error2')
];
// Get all successful results (returns immediately when there are successes)
PromiseLogic.allFulfilled(operations).then((results) => {
console.log('Successful results:', results); // ['success1', 'success2']
});
// Get all failed results (returns immediately when there are failures)
PromiseLogic.allRejected(operations).then((errors) => {
console.log('Failed results:', errors); // ['error1', 'error2']
});
// Get all results (both success and failure)
PromiseLogic.allSettled(operations).then((results) => {
console.log('All results:', results);
});import { PromiseLogic } from 'promise-logic';
// Custom error type
const CUSTOM_ERROR_TYPE = 'CUSTOM_ERROR';
// Custom error message
const CUSTOM_ERROR_MESSAGE = 'Custom error message';
// Use custom error type and message
PromiseLogic.and([Promise.resolve('success1'), Promise.reject('error1')], {
errorType: CUSTOM_ERROR_TYPE,
errorMessage: CUSTOM_ERROR_MESSAGE
})
.then((results) => {
console.log(results);
})
.catch((error) => {
if (error.type === CUSTOM_ERROR_TYPE) {
console.error(error); // Output: Custom error message
} else {
console.error(error);
}
});The factory function allows you to create PromiseLogic methods with custom names:
import { createPromiseLogic } from 'promise-logic';
// Create instance with custom naming
const logic = createPromiseLogic({
prefix: 'api_',
suffix: '_call',
rename: {
and: 'all',
or: 'any',
xor: 'exclusive'
}
});
// Use custom-named methods
logic.api_all_call([fetch('/api/users'), fetch('/api/posts')]);
logic.api_any_call([fetch('/api/cache'), fetch('/api/database')]);import { PromiseLogic } from 'promise-logic/typescript';
// Type inference
PromiseLogic.and([Promise.resolve(1), Promise.resolve(2)]).then(
(results: number[]) => {
console.log(results);
}
);
// Type assertion
PromiseLogic.and<number>([Promise.resolve(1), Promise.resolve(2)]);import { PromiseLogic } from 'promise-logic';
// Dynamic nesting example: adjust logistics strategy based on user level
const orderFlow = async (userLevel) => {
// VIP users: dual high-availability logistics guarantee (at least one success)
// Normal users: priority standard logistics, failover to economy logistics (at least one success)
const logisticsStrategy = userLevel === 'VIP'
? PromiseLogic.or([premiumLogistics(), backupLogistics()])
: PromiseLogic.or([standardLogistics(), economyLogistics()]);
return await PromiseLogic.and([
PromiseLogic.and([paymentAPI(), inventoryAPI()]), // Payment + inventory atomic operations
logisticsStrategy, // Logistics strategy
couponValidation() // Coupon validation
]);
};| API | Description |
|---|---|
and |
All Promises succeed, returns result array; any failure causes overall failure. Equivalent to native Promise.all. |
or |
At least one Promise succeeds, returns first success result; all failures cause overall failure. Equivalent to native Promise.any. |
xor |
Exactly one Promise succeeds, returns that result; otherwise throws XOR_ERROR. |
nand |
Not all Promises succeed (at least one fails), returns success result array; all succeed causes overall failure. |
nor |
All Promises fail (no task succeeds), returns empty array; any success causes overall failure. |
xnor |
All Promises succeed or all fail (same state), returns success result array; otherwise throws XNOR_ERROR. |
not |
Inverts the result of a single Promise: success becomes failure, failure becomes success. |
majority |
More than specified threshold of Promises succeed, returns success result array; otherwise overall failure. Accepts options parameter, where max property can customize threshold (default: 0.5), range: [0, 1]. |
allFulfilled |
Returns all successful results as an array, ignoring failures. Returns immediately when a result exists, while maintaining consistent input and output order. |
allRejected |
Returns all failed results as an array, ignoring successes. Returns immediately when a result exists, while maintaining consistent input and output order. |
allSettled |
Returns all results (both successful and failed) as an array. Equivalent to native Promise.allSettled. |
race |
Returns the first completed Promise result (regardless of success or failure). Equivalent to native Promise.race. |
maxTimer |
Adds timeout functionality to any Promise operation (unit: milliseconds). Supports custom timeout error messages. |
Error Mechanism Improvements
- Added
errorTypeanderrorMessageparameters to logic gates, supporting custom error types and messages, further fitting business scenarios - Optimized the existing error type system to ensure correct TypeScript type definitions
- Optimized TypeScript type compatibility issues
- Optimized allSettled gate return type error messages
- Improved test scripts, covering most promise combination logic boundaries and tricky scenario issues, ensuring more stable operation of logic gates
- Optimized logic gate execution efficiency, reducing unnecessary Promise wrapping
- Performance optimization: Optimized
allFulfilledandallRejectedimplementation logic from the bottom layer, existing results return immediately while maintaining consistent input and output order - Added chain timeout control with custom error messages: Can customize timeout error messages in the
maxTimermethod - Type fixes: Fixed TypeScript version type declaration issues
- Test completion: Added complete test cases for
allFulfilled,allRejected, andmaxTimer - Code refactoring: Improved code structure for better maintainability
git clone https://github.com/xier123456/promise-logic.git
cd promise-logic
npm installnpm test- Commit messages must include prefixes like
feat:(new feature),fix:(bug fix),docs:(documentation). - Pull Requests must include test cases.
- GitHub Repository: https://github.com/xier123456/promise-logic
- npm Package: https://www.npmjs.com/package/promise-logic
- Issue Tracking: GitHub Issues