feat: atomic async function

This commit is contained in:
EnixCoda 2022-07-02 23:23:51 +08:00
parent b112de229e
commit bcc34949ab
2 changed files with 43 additions and 1 deletions

View file

@ -1,4 +1,4 @@
import { resolveDiffGraphMeta } from './general'
import { atomicAsyncFunction, resolveDiffGraphMeta } from './general'
it(`should resolve diff stat graph meta properly`, () => {
const example = `
@ -27,3 +27,37 @@ it(`should resolve diff stat graph meta properly`, () => {
expect([meta.g, meta.r]).toEqual([g, r])
})
})
it(`should schedule atomic promises properly`, async () => {
const sleep = (duration: number) => new Promise(resolve => setTimeout(resolve, duration))
const recorder: string[] = []
const sleepWithNoise = async (duration: number, noise: string) => {
await sleep(duration)
recorder.push(noise)
return noise
}
const atomicSleep = atomicAsyncFunction(sleepWithNoise)
recorder.length = 0
const atomicReturns = await Promise.all([atomicSleep(200, 'a'), atomicSleep(100, 'b')])
// Expected time sheet
// 0 100 200 300
// [a ]
// [b ]
// Recorder: [a, b]
//
expect(recorder).toEqual(['a', 'b'])
expect(atomicReturns).toEqual(['a', 'b'])
recorder.length = 0
const normalReturns = await Promise.all([sleepWithNoise(200, 'a'), sleepWithNoise(100, 'b')])
// Time sheet if not atomic
// 0 100 200
// [a ]
// [b ]
// Recorder: [b, a]
expect(recorder).toEqual(['b', 'a'])
expect(normalReturns).toEqual(['a', 'b'])
})

View file

@ -219,3 +219,11 @@ export function resolveDiffGraphMeta(additions: number, deletions: number, chang
w = 5 - g - r
return { g, r, w }
}
export function atomicAsyncFunction<Args extends any[], R>(fn: (...args: Args) => Promise<R>) {
let last: Promise<R> | undefined
return async (...args: Args) => {
last = last ? last.then(() => fn(...args)) : fn(...args)
return last
}
}