Skip to content

Commit

Permalink
Merge af85bf6 into 543af9f
Browse files Browse the repository at this point in the history
  • Loading branch information
nicolas-van committed Dec 29, 2023
2 parents 543af9f + af85bf6 commit 8dccd3a
Show file tree
Hide file tree
Showing 93 changed files with 2,165 additions and 2,668 deletions.
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,11 +35,11 @@ Or use [jsDelivr](https://www.jsdelivr.com/package/npm/modern-async) to get the
## Usage

```javascript
import { map, sleep } from 'modern-async'
import { asyncMap, asyncSleep } from 'modern-async'

const array = [1, 2, 3]
const result = await map(array, async (v) => {
await sleep(10)
const result = await asyncMap(array, async (v) => {
await asyncSleep(10)
return v * 2
})
console.log(result)
Expand Down
236 changes: 83 additions & 153 deletions modern-async.d.ts

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions src/Deferred.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,11 @@
* internally and can be useful to code other asynchronous helpers.
*
* @example
* import { Deferred, sleep } from 'modern-async'
* import { Deferred, asyncSleep } from 'modern-async'
*
* const deferred = new Deferred()
*
* sleep(10).then(() => {
* asyncSleep(10).then(() => {
* deferred.resolve('test')
* })
*
Expand Down
8 changes: 4 additions & 4 deletions src/Delayer.mjs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@

import delay from './delay.mjs'
import asyncDelay from './asyncDelay.mjs'
import assert from 'nanoassert'

/**
Expand All @@ -15,7 +15,7 @@ import assert from 'nanoassert'
* at the end of every loop. `checkDelay()` will check the amount of time that ellasped since the last time
* it triggered a new task in the event loop. If the amount of time is below the trigger time it returns
* an already resolved promise and the remaining computation will be able to continue processing in a
* microtask. If not it will call the `delay()` function that will retrigger the operation in a later task
* microtask. If not it will call the `asyncDelay()` function that will retrigger the operation in a later task
* of the event loop.
*
* @example
Expand Down Expand Up @@ -69,14 +69,14 @@ class Delayer {

/**
* Checks if a delay must be applied according to the internal timer. If that's the case this method
* will call `delay()` and return `true`. If not it will do nothing and return `false`.
* will call `asyncDelay()` and return `true`. If not it will do nothing and return `false`.
*
* @returns {boolean} `true` if a new task was scheduled in the event loop, `false` otherwise.
*/
async checkDelay () {
const current = new Date().getTime()
if (current - this._last >= this.triggerTime) {
await delay()
await asyncDelay()
this.reset()
return true
} else {
Expand Down
4 changes: 2 additions & 2 deletions src/Queue.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import queueMicrotask from './queueMicrotask.mjs'
* Once a task is completed, its corresponding promise is terminated accordingly.
*
* @example
* import { Queue, sleep } from 'modern-async'
* import { Queue, asyncSleep } from 'modern-async'
*
* const queue = new Queue(3) // create a queue with concurrency 3
*
Expand All @@ -25,7 +25,7 @@ import queueMicrotask from './queueMicrotask.mjs'
* for (const i of array) {
* promises.push(queue.exec(async () => {
* console.log(`Starting task ${i}`)
* await sleep(Math.random() * 10) // waits a random amount of time between 0ms and 10ms
* await asyncSleep(Math.random() * 10) // waits a random amount of time between 0ms and 10ms
* console.log(`Ending task ${i}`)
* return i;
* }))
Expand Down
6 changes: 3 additions & 3 deletions src/Queue.test.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import Queue from './Queue.mjs'
import Deferred from './Deferred.mjs'
import CancelledError from './CancelledError.mjs'
import { range } from 'itertools'
import delay from './delay.mjs'
import asyncDelay from './asyncDelay.mjs'

test('Queue base 1', async () => {
const queue = new Queue(1)
Expand Down Expand Up @@ -565,7 +565,7 @@ test('Queue concurrency 1 priority', async () => {
})

test('Queue all resolve in micro tasks', async () => {
const del = delay()
const del = asyncDelay()
const queue = new Queue(1)
const ps = []
ps.push(queue.exec(async () => {}))
Expand All @@ -580,7 +580,7 @@ test('Queue all resolve in micro tasks', async () => {
})

test('Queue infinity all resolve in micro tasks', async () => {
const del = delay()
const del = asyncDelay()
const queue = new Queue(Number.POSITIVE_INFINITY)
const ps = []
ps.push(queue.exec(async () => {}))
Expand Down
12 changes: 6 additions & 6 deletions src/Scheduler.mjs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@

import sleepCancellable from './sleepCancellable.mjs'
import asyncSleepCancellable from './asyncSleepCancellable.mjs'
import Queue from './Queue.mjs'
import assert from 'nanoassert'
import asyncWrap from './asyncWrap.mjs'
Expand All @@ -12,22 +12,22 @@ import CancelledError from './CancelledError.mjs'
* tasks. Notably it can limit the concurrency of asynchronous tasks running in parallel.
*
* @example
* import { Scheduler, sleep } from 'modern-async'
* import { Scheduler, asyncSleep } from 'modern-async'
*
* let i = 0
* const scheduler = new Scheduler(async () => {
* const taskNbr = i
* i += 1
* console.log(`Starting task ${taskNbr}`)
* await sleep(10) // waits 10ms
* await asyncSleep(10) // waits 10ms
* console.log(`Ending task ${taskNbr}`)
* }, 100) // a scheduler that triggers every 100ms
* // the default configuration uses a maximum concurrency of 1 and doesn't allow pending
* // tasks, which mean that if a task takes more time to complete than the delay it will be skipped
*
* scheduler.start() // starts the scheduler
*
* await sleep(1000) // waits 1s, during that time the task should trigger ~ 9 times
* await asyncSleep(1000) // waits 1s, during that time the task should trigger ~ 9 times
*
* scheduler.stop() // stops the scheduler
* console.log('Scheduler stopped')
Expand Down Expand Up @@ -198,13 +198,13 @@ class Scheduler {
this._nbrTriggering += 1
const nextTime = this._initialTime + (this.delay * this._nbrTriggering)
const currentTime = new Date().getTime()
const [promise, cancel] = sleepCancellable(nextTime - currentTime)
const [promise, cancel] = asyncSleepCancellable(nextTime - currentTime)
this._cancelSleep = cancel
promise.then(() => {
this._triggerTask()
this._scheduleSleep()
}, () => {
// ignore cancelled sleep
// ignore cancelled asyncSleep
})
}

Expand Down
20 changes: 10 additions & 10 deletions src/Scheduler.test.mjs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@

import { expect, test } from '@jest/globals'
import sleepPrecise from './sleepPrecise.mjs'
import asyncSleepPrecise from './asyncSleepPrecise.mjs'
import Scheduler, { exceptionHandler } from './Scheduler.mjs'
import CancelledError from './CancelledError.mjs'
import Deferred from './Deferred.mjs'
Expand All @@ -21,7 +21,7 @@ test('Scheduler base', async () => {
scheduler.start()
expect(scheduler.started).toBe(true)
d.resolve()
await sleepPrecise(unit * 1.5 * 3)
await asyncSleepPrecise(unit * 1.5 * 3)
scheduler.stop()
expect(scheduler.started).toBe(false)
expect(callCount).toBeGreaterThanOrEqual(3)
Expand All @@ -45,7 +45,7 @@ test('Scheduler multi start stop', async () => {
scheduler.start()
expect(scheduler.started).toBe(true)
d.resolve()
await sleepPrecise(unit * 1.5 * 3)
await asyncSleepPrecise(unit * 1.5 * 3)
scheduler.stop()
expect(scheduler.started).toBe(false)
scheduler.stop()
Expand All @@ -71,7 +71,7 @@ test('Scheduler startImmediate', async () => {
scheduler.start()
expect(scheduler.started).toBe(true)
d.resolve()
await sleepPrecise(unit * 1.5 * 3)
await asyncSleepPrecise(unit * 1.5 * 3)
scheduler.stop()
expect(scheduler.started).toBe(false)
expect(callCount).toBeGreaterThanOrEqual(4)
Expand All @@ -87,13 +87,13 @@ test('Scheduler concurrency 1', async () => {
expect(scheduler.started).toBe(false)
scheduler.start()
expect(scheduler.started).toBe(true)
await sleepPrecise(100)
await asyncSleepPrecise(100)
d.resolve()
expect(scheduler._queue.pending).toBe(0)
scheduler.stop()
expect(scheduler.started).toBe(false)
expect(callCount).toBe(1)
await sleepPrecise(100)
await asyncSleepPrecise(100)
expect(callCount).toBe(1)
})

Expand All @@ -109,14 +109,14 @@ test('Scheduler pending', async () => {
expect(scheduler.started).toBe(false)
scheduler.start()
expect(scheduler.started).toBe(true)
await sleepPrecise(150)
await asyncSleepPrecise(150)
expect(scheduler._queue.pending).toBeGreaterThan(3)
scheduler.stop()
expect(scheduler._queue.pending).toBe(0)
expect(scheduler.started).toBe(false)
expect(callCount).toBe(1)
d.resolve()
await sleepPrecise(150)
await asyncSleepPrecise(150)
expect(callCount).toBe(1)
})

Expand All @@ -132,13 +132,13 @@ test('Scheduler concurrency 2', async () => {
expect(scheduler.started).toBe(false)
scheduler.start()
expect(scheduler.started).toBe(true)
await sleepPrecise(150)
await asyncSleepPrecise(150)
expect(scheduler._queue.pending).toBe(0)
scheduler.stop()
expect(scheduler.started).toBe(false)
expect(callCount).toBe(2)
d.resolve()
await sleepPrecise(150)
await asyncSleepPrecise(150)
expect(callCount).toBe(2)
})

Expand Down
12 changes: 6 additions & 6 deletions src/delay.mjs → src/asyncDelay.mjs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@

import delayCancellable from './delayCancellable.mjs'
import asyncDelayCancellable from './asyncDelayCancellable.mjs'

/**
* A function returning a promise that will be resolved in a later task of the event loop.
Expand All @@ -8,14 +8,14 @@ import delayCancellable from './delayCancellable.mjs'
*
* @returns {Promise<void>} A promise that will be resolved on a later tick of the event loop.
* @example
* import { delay } from 'modern-async'
* import { asyncDelay } from 'modern-async'
*
* console.log('this executes in a tick of the event loop')
* await delay()
* await asyncDelay()
* console.log('this executes in another tick of the event loop')
*/
async function delay () {
return delayCancellable()[0]
async function asyncDelay () {
return asyncDelayCancellable()[0]
}

export default delay
export default asyncDelay
6 changes: 3 additions & 3 deletions src/delay.test.mjs → src/asyncDelay.test.mjs
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@

import { test, expect } from '@jest/globals'
import delay from './delay.mjs'
import asyncDelay from './asyncDelay.mjs'

test('delay', async () => {
test('asyncDelay', async () => {
const events = []
const p = delay().then(() => {
const p = asyncDelay().then(() => {
events.push('resolved')
})
Promise.resolve().then(() => {
Expand Down
8 changes: 4 additions & 4 deletions src/delayCancellable.mjs → src/asyncDelayCancellable.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -17,17 +17,17 @@ import clearImmediate from 'core-js-pure/features/clear-immediate.js'
* * The cancel function. It will return a boolean that will be true if the promise was effectively cancelled,
* false otherwise.
* @example
* import { delayCancellable, CancelledError } from 'modern-async'
* import { asyncDelayCancellable, CancelledError } from 'modern-async'
*
* const [promise, cancel] = delayCancellable()
* const [promise, cancel] = asyncDelayCancellable()
* cancel()
* try {
* await promise
* } catch (e) {
* console.log(e instanceof CancelledError) // prints true
* }
*/
function delayCancellable () {
function asyncDelayCancellable () {
const deferred = new Deferred()
const id = setImmediate(deferred.resolve)
let terminated = false
Expand All @@ -45,4 +45,4 @@ function delayCancellable () {
}]
}

export default delayCancellable
export default asyncDelayCancellable
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@

import { expect, test } from '@jest/globals'
import delayCancellable from './delayCancellable.mjs'
import asyncDelayCancellable from './asyncDelayCancellable.mjs'
import CancelledError from './CancelledError.mjs'

test('delayCancellable', async () => {
test('asyncDelayCancellable', async () => {
const events = []
const p = delayCancellable()[0].then(() => {
const p = asyncDelayCancellable()[0].then(() => {
events.push('resolved')
})
Promise.resolve().then(() => {
Expand All @@ -16,8 +16,8 @@ test('delayCancellable', async () => {
expect(events).toStrictEqual(['microtask', 'resolved'])
})

test('delayCancellable cancel', async () => {
const [p, cancel] = delayCancellable()
test('asyncDelayCancellable cancel', async () => {
const [p, cancel] = asyncDelayCancellable()
const res = cancel()
expect(res).toBe(true)
try {
Expand Down
Loading

0 comments on commit 8dccd3a

Please sign in to comment.