0
# Object Promise Utilities
1
2
Functions for working with objects containing promises, useful for handling named async operations and maintaining key-based result organization.
3
4
## Capabilities
5
6
### hash
7
8
Wait for all promises in an object to fulfill, or fail fast on first rejection.
9
10
```javascript { .api }
11
/**
12
* Wait for all object values to resolve, maintaining key structure
13
* @param object - Object with promises or values as properties
14
* @param label - Optional string for debugging/tooling
15
* @returns Promise that fulfills with object containing resolved values
16
*/
17
function hash(object: Object, label?: string): Promise;
18
```
19
20
**Usage Examples:**
21
22
```javascript
23
import { hash, resolve } from "rsvp";
24
25
// Basic usage with named promises
26
hash({
27
user: fetchUser(123),
28
posts: fetchUserPosts(123),
29
settings: fetchUserSettings(123)
30
}).then(function(results) {
31
console.log("User:", results.user);
32
console.log("Posts:", results.posts);
33
console.log("Settings:", results.settings);
34
}).catch(function(error) {
35
console.error("At least one operation failed:", error);
36
});
37
38
// Mixed promises and immediate values
39
hash({
40
immediate: "value",
41
promised: resolve("async value"),
42
fetched: fetchData()
43
}).then(function(results) {
44
// results.immediate === "value"
45
// results.promised === "async value"
46
// results.fetched === result from fetchData()
47
});
48
49
// Nested object structure
50
hash({
51
api: {
52
users: fetchUsers(),
53
posts: fetchPosts()
54
},
55
config: loadConfig(),
56
permissions: checkPermissions()
57
}).then(function(results) {
58
// Note: Only top-level values are processed
59
// results.api will be the literal object, not processed
60
console.log("Config:", results.config);
61
console.log("Permissions:", results.permissions);
62
});
63
```
64
65
### hashSettled
66
67
Wait for all promises in an object to settle (fulfill or reject), collecting all results with state information.
68
69
```javascript { .api }
70
/**
71
* Wait for all object values to settle regardless of outcome
72
* @param object - Object with promises or values as properties
73
* @param label - Optional string for debugging/tooling
74
* @returns Promise with object containing {state, value/reason} for each key
75
*/
76
function hashSettled(object: Object, label?: string): Promise;
77
```
78
79
**Usage Examples:**
80
81
```javascript
82
import { hashSettled, resolve, reject } from "rsvp";
83
84
hashSettled({
85
success: resolve("worked"),
86
failure: reject(new Error("failed")),
87
immediate: 42
88
}).then(function(results) {
89
// results.success === { state: 'fulfilled', value: 'worked' }
90
// results.failure === { state: 'rejected', reason: Error }
91
// results.immediate === { state: 'fulfilled', value: 42 }
92
93
// Process results based on state
94
Object.keys(results).forEach(key => {
95
const result = results[key];
96
if (result.state === 'fulfilled') {
97
console.log(`${key} succeeded:`, result.value);
98
} else {
99
console.error(`${key} failed:`, result.reason);
100
}
101
});
102
});
103
104
// Practical example: Multiple API endpoints
105
hashSettled({
106
users: fetch('/api/users').then(r => r.json()),
107
posts: fetch('/api/posts').then(r => r.json()),
108
comments: fetch('/api/comments').then(r => r.json())
109
}).then(function(results) {
110
const successful = Object.keys(results)
111
.filter(key => results[key].state === 'fulfilled')
112
.reduce((acc, key) => {
113
acc[key] = results[key].value;
114
return acc;
115
}, {});
116
117
const failed = Object.keys(results)
118
.filter(key => results[key].state === 'rejected')
119
.map(key => ({ endpoint: key, error: results[key].reason }));
120
121
console.log("Loaded data:", successful);
122
if (failed.length > 0) {
123
console.warn("Failed endpoints:", failed);
124
}
125
});
126
```
127
128
## Key Features and Limitations
129
130
### Prototype Chain Handling
131
132
Both `hash` and `hashSettled` work only with own properties, not inherited properties:
133
134
```javascript
135
import { hash, resolve } from "rsvp";
136
137
function MyConstructor() {
138
this.example = resolve('Example');
139
}
140
141
MyConstructor.prototype = {
142
protoProperty: resolve('Proto Property')
143
};
144
145
const myObject = new MyConstructor();
146
147
hash(myObject).then(function(result) {
148
// result.example === 'Example' (own property)
149
// result.protoProperty is undefined (inherited property ignored)
150
console.log(result.hasOwnProperty('protoProperty')); // false
151
});
152
```
153
154
### Type Validation
155
156
Both functions validate that the input is a proper object:
157
158
```javascript
159
import { hash, hashSettled } from "rsvp";
160
161
// These will throw TypeError
162
hash(null).catch(error => console.error(error.message));
163
// "Promise.hash must be called with an object"
164
165
hashSettled("not an object").catch(error => console.error(error.message));
166
// "hashSettled must be called with an object"
167
168
// Valid inputs
169
hash({}); // Empty object - resolves immediately
170
hash({ key: "value" }); // Object with properties
171
```
172
173
### Error Handling Patterns
174
175
```javascript
176
import { hash, hashSettled } from "rsvp";
177
178
// hash - fail fast on first rejection
179
hash({
180
good: resolve("success"),
181
bad: reject(new Error("failure")),
182
other: resolve("ignored") // Won't be processed due to early failure
183
}).catch(function(error) {
184
console.error("First error encountered:", error);
185
});
186
187
// hashSettled - collect all results
188
hashSettled({
189
good: resolve("success"),
190
bad: reject(new Error("failure")),
191
other: resolve("also processed")
192
}).then(function(results) {
193
// All operations completed, check individual states
194
const hasFailures = Object.values(results)
195
.some(result => result.state === 'rejected');
196
});
197
```
198
199
## Common Use Cases
200
201
### API Data Loading
202
203
```javascript
204
// Load related data sets
205
hash({
206
profile: fetchUserProfile(userId),
207
preferences: fetchUserPreferences(userId),
208
notifications: fetchNotifications(userId)
209
}).then(function(data) {
210
renderUserDashboard(data.profile, data.preferences, data.notifications);
211
});
212
```
213
214
### Configuration Loading
215
216
```javascript
217
// Load multiple config sources with fallback handling
218
hashSettled({
219
userConfig: loadUserConfig(),
220
defaultConfig: loadDefaultConfig(),
221
envConfig: loadEnvironmentConfig()
222
}).then(function(configs) {
223
const mergedConfig = Object.values(configs)
224
.filter(c => c.state === 'fulfilled')
225
.map(c => c.value)
226
.reduce((merged, config) => ({ ...merged, ...config }), {});
227
});
228
```