Skip to content

Commit 6f50f1c

Browse files
committed
Added base snapshot function
1 parent 08a94a5 commit 6f50f1c

File tree

3 files changed

+90
-0
lines changed

3 files changed

+90
-0
lines changed

src/modern-async.mjs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,3 +43,4 @@ export { default as timeout } from './timeout.mjs'
4343
export { default as TimeoutError } from './TimeoutError.mjs'
4444
export { default as timeoutPrecise } from './timeoutPrecise.mjs'
4545
export { default as toArray } from './toArray.mjs'
46+
export { default as snapshot } from './snapshot.mjs'

src/snapshot.mjs

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
2+
/**
3+
* Immediately calls an asynchronous function and wraps its result into a promise that
4+
* can only be resolved, not rejected, regardless of the state of the promised returned
5+
* by the function.
6+
*
7+
* The returned promise will contain an object with the following fields:
8+
*
9+
* * `status`: A string, either "fulfilled" or "rejected", indicating the state of the
10+
* original promise.
11+
* * `value`: Only present if status is "fulfilled". The value that the promise was
12+
* fulfilled with.
13+
* * `reason`: Only present if status is "rejected". The reason that the promise was
14+
* rejected with.
15+
*
16+
* This object structure is similar to the one used by the [`Promise.allSettled()`
17+
* function](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/allSettled).
18+
*
19+
* This function can be useful to make use of other functions in a fault-tolerant way.
20+
*
21+
* @param {Function} fct An asynchronous function
22+
* @returns {Promise<any>} A promise that will always be resolved with an object containing
23+
* a snapshot of the original promise state.
24+
* @example
25+
* import { snapshot, map, sleep } from 'modern-async'
26+
*
27+
* const array = [1, 2, 3]
28+
*
29+
* const result = await map(array, (v) => snapshot(async () => {
30+
* await sleep(10) // waits 10ms
31+
* if (v % 2 === 0) { // throws error on some values
32+
* throw Error("error")
33+
* }
34+
* return v
35+
* }))
36+
*
37+
* console.log(result)
38+
* // prints:
39+
* // [
40+
* // { status: 'fulfilled', value: 1 },
41+
* // { status: 'rejected', reason: Error: error },
42+
* // { status: 'fulfilled', value: 3 }
43+
* // ]
44+
*/
45+
async function snapshot (fct) {
46+
try {
47+
const res = await fct()
48+
return {
49+
status: 'fulfilled',
50+
value: res
51+
}
52+
} catch (e) {
53+
return {
54+
status: 'rejected',
55+
reason: e
56+
}
57+
}
58+
}
59+
60+
export default snapshot

src/snapshot.test.mjs

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
2+
import { expect, test } from '@jest/globals'
3+
import snapshot from './snapshot.mjs'
4+
import delay from './delay.mjs'
5+
6+
test('snapshot base test', async () => {
7+
const res1 = await snapshot(async () => {
8+
await delay()
9+
return 3
10+
})
11+
12+
expect(typeof (res1) === 'object').toBeTruthy()
13+
expect(res1.status).toStrictEqual('fulfilled')
14+
expect(res1.value).toStrictEqual(3)
15+
expect(res1.reason).toBeUndefined()
16+
})
17+
18+
test('snapshot falure', async () => {
19+
const res1 = await snapshot(async () => {
20+
await delay()
21+
throw new Error('error')
22+
})
23+
24+
expect(typeof (res1) === 'object').toBeTruthy()
25+
expect(res1.status).toStrictEqual('rejected')
26+
expect(res1.value).toBeUndefined()
27+
expect(res1.reason).toBeInstanceOf(Error)
28+
expect(res1.reason.message).toStrictEqual('error')
29+
})

0 commit comments

Comments
 (0)