A lightweight library that provides tools for organizing asynchronous code
—
Functions for working with objects containing promises, useful for handling named async operations and maintaining key-based result organization.
Wait for all promises in an object to fulfill, or fail fast on first rejection.
/**
* Wait for all object values to resolve, maintaining key structure
* @param object - Object with promises or values as properties
* @param label - Optional string for debugging/tooling
* @returns Promise that fulfills with object containing resolved values
*/
function hash(object: Object, label?: string): Promise;Usage Examples:
import { hash, resolve } from "rsvp";
// Basic usage with named promises
hash({
user: fetchUser(123),
posts: fetchUserPosts(123),
settings: fetchUserSettings(123)
}).then(function(results) {
console.log("User:", results.user);
console.log("Posts:", results.posts);
console.log("Settings:", results.settings);
}).catch(function(error) {
console.error("At least one operation failed:", error);
});
// Mixed promises and immediate values
hash({
immediate: "value",
promised: resolve("async value"),
fetched: fetchData()
}).then(function(results) {
// results.immediate === "value"
// results.promised === "async value"
// results.fetched === result from fetchData()
});
// Nested object structure
hash({
api: {
users: fetchUsers(),
posts: fetchPosts()
},
config: loadConfig(),
permissions: checkPermissions()
}).then(function(results) {
// Note: Only top-level values are processed
// results.api will be the literal object, not processed
console.log("Config:", results.config);
console.log("Permissions:", results.permissions);
});Wait for all promises in an object to settle (fulfill or reject), collecting all results with state information.
/**
* Wait for all object values to settle regardless of outcome
* @param object - Object with promises or values as properties
* @param label - Optional string for debugging/tooling
* @returns Promise with object containing {state, value/reason} for each key
*/
function hashSettled(object: Object, label?: string): Promise;Usage Examples:
import { hashSettled, resolve, reject } from "rsvp";
hashSettled({
success: resolve("worked"),
failure: reject(new Error("failed")),
immediate: 42
}).then(function(results) {
// results.success === { state: 'fulfilled', value: 'worked' }
// results.failure === { state: 'rejected', reason: Error }
// results.immediate === { state: 'fulfilled', value: 42 }
// Process results based on state
Object.keys(results).forEach(key => {
const result = results[key];
if (result.state === 'fulfilled') {
console.log(`${key} succeeded:`, result.value);
} else {
console.error(`${key} failed:`, result.reason);
}
});
});
// Practical example: Multiple API endpoints
hashSettled({
users: fetch('/api/users').then(r => r.json()),
posts: fetch('/api/posts').then(r => r.json()),
comments: fetch('/api/comments').then(r => r.json())
}).then(function(results) {
const successful = Object.keys(results)
.filter(key => results[key].state === 'fulfilled')
.reduce((acc, key) => {
acc[key] = results[key].value;
return acc;
}, {});
const failed = Object.keys(results)
.filter(key => results[key].state === 'rejected')
.map(key => ({ endpoint: key, error: results[key].reason }));
console.log("Loaded data:", successful);
if (failed.length > 0) {
console.warn("Failed endpoints:", failed);
}
});Both hash and hashSettled work only with own properties, not inherited properties:
import { hash, resolve } from "rsvp";
function MyConstructor() {
this.example = resolve('Example');
}
MyConstructor.prototype = {
protoProperty: resolve('Proto Property')
};
const myObject = new MyConstructor();
hash(myObject).then(function(result) {
// result.example === 'Example' (own property)
// result.protoProperty is undefined (inherited property ignored)
console.log(result.hasOwnProperty('protoProperty')); // false
});Both functions validate that the input is a proper object:
import { hash, hashSettled } from "rsvp";
// These will throw TypeError
hash(null).catch(error => console.error(error.message));
// "Promise.hash must be called with an object"
hashSettled("not an object").catch(error => console.error(error.message));
// "hashSettled must be called with an object"
// Valid inputs
hash({}); // Empty object - resolves immediately
hash({ key: "value" }); // Object with propertiesimport { hash, hashSettled } from "rsvp";
// hash - fail fast on first rejection
hash({
good: resolve("success"),
bad: reject(new Error("failure")),
other: resolve("ignored") // Won't be processed due to early failure
}).catch(function(error) {
console.error("First error encountered:", error);
});
// hashSettled - collect all results
hashSettled({
good: resolve("success"),
bad: reject(new Error("failure")),
other: resolve("also processed")
}).then(function(results) {
// All operations completed, check individual states
const hasFailures = Object.values(results)
.some(result => result.state === 'rejected');
});// Load related data sets
hash({
profile: fetchUserProfile(userId),
preferences: fetchUserPreferences(userId),
notifications: fetchNotifications(userId)
}).then(function(data) {
renderUserDashboard(data.profile, data.preferences, data.notifications);
});// Load multiple config sources with fallback handling
hashSettled({
userConfig: loadUserConfig(),
defaultConfig: loadDefaultConfig(),
envConfig: loadEnvironmentConfig()
}).then(function(configs) {
const mergedConfig = Object.values(configs)
.filter(c => c.state === 'fulfilled')
.map(c => c.value)
.reduce((merged, config) => ({ ...merged, ...config }), {});
});Install with Tessl CLI
npx tessl i tessl/npm-rsvp