Skip to content

Commit

Permalink
Remove Node.js dependency (events core usage) to ensure browser com…
Browse files Browse the repository at this point in the history
…patibility
  • Loading branch information
jpwilliams committed Feb 13, 2022
1 parent d3526c2 commit 98b87d6
Show file tree
Hide file tree
Showing 3 changed files with 34 additions and 23 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

![npm version](https://img.shields.io/npm/v/@jpwilliams/waitgroup) ![Test on push](https://github.com/jpwilliams/waitgroup/workflows/Test%20on%20push/badge.svg) ![Downloads](https://img.shields.io/npm/dm/@jpwilliams/waitgroup)

A tiny version of Golang's [WaitGroup](https://golang.org/pkg/sync/#WaitGroup) with typings, promises, and zero dependencies.
A tiny version of Golang's [WaitGroup](https://golang.org/pkg/sync/#WaitGroup) for Node.js and the browser with typings, promises, and zero dependencies.

```sh
npm install @jpwilliams/waitgroup
Expand Down
8 changes: 4 additions & 4 deletions src/index.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,13 +42,13 @@ describe('WaitGroup', () => {
test('increments internal counter by default of 1', () => {
const wg = new WaitGroup()
wg.add()
expect(wg['_current']).toEqual(1)
expect(wg['current']).toEqual(1)
})

test('increments internal counter given value', () => {
const wg = new WaitGroup()
wg.add(3)
expect(wg['_current']).toEqual(3)
expect(wg['current']).toEqual(3)
})

test('throws if add() results in a negative counter', () => {
Expand All @@ -61,9 +61,9 @@ describe('WaitGroup', () => {
test('decrements internal counter by 1', () => {
const wg = new WaitGroup()
wg.add(3)
expect(wg['_current']).toEqual(3)
expect(wg['current']).toEqual(3)
wg.done()
expect(wg['_current']).toEqual(2)
expect(wg['current']).toEqual(2)
})

test('throws if done() results in a negative counter', () => {
Expand Down
47 changes: 29 additions & 18 deletions src/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
import { EventEmitter } from 'events'

/**
* A WaitGroup waits for a collection of actions to finish.
* The main goroutine calls `add` to set the number of actions to wait for.
Expand All @@ -10,35 +8,48 @@ import { EventEmitter } from 'events'
* way Node functions, meaning `add`, `done` and `wait` can be called at any time, in any order.
*/
export class WaitGroup {
private _current = 0
private _emitter = new EventEmitter()
private current = 0
private queued: (() => void)[] = []

private queue (fn: () => void) {
if (this.current === 0) {
fn()
} else {
this.queued.push(fn)
}
}

private resolveQueue () {
while (this.queued.length > 0) {
this.queued.shift()?.()
}
}

/**
* Adds a delta, which may be negative, to the WaitGroup counter.
* If the counter becomes zero, all promises returned from `wait` are resolved.
* If the counter goes negative, an error is thrown.
*/
* Adds a delta, which may be negative, to the WaitGroup counter.
* If the counter becomes zero, all promises returned from `wait` are resolved.
* If the counter goes negative, an error is thrown.
*/
public add (delta: number = 1): void {
this._current += delta
if (this._current < 0) throw new Error('Negative WaitGroup counter')
if (this._current === 0) this._emitter.emit('done')
this.current += delta
if (this.current < 0) throw new Error('Negative WaitGroup counter')
if (this.current === 0) this.resolveQueue()
}

/**
* Decrements the WaitGroup counter by one.
*/
* Decrements the WaitGroup counter by one.
*/
public done (): void {
this.add(-1)
}

/**
* Returns a promise that resolves when the WaitGroup counter is zero.
* If the counter is zero when the method is called, it's resolved immediately.
*/
* Returns a promise that resolves when the WaitGroup counter is zero.
* If the counter is zero when the method is called, it's resolved immediately.
*/
public wait (): Promise<void> {
return new Promise((resolve) => {
if (this._current === 0) return resolve()
this._emitter.once('done', () => resolve())
this.queue(() => resolve())
})
}
}

0 comments on commit 98b87d6

Please sign in to comment.