Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
b1ac70a
commit f3fb4cc
Showing
3 changed files
with
182 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
# TODO | ||
|
||
* AbortError subclass for abort due to collection completion? | ||
* Tests for Collections awaiting all promises if iteration error and `await` option set | ||
* Collections handle where getting `.abort` or `[IS_ABORTABLE]` properties throws error | ||
* Collections handle where calling `.abort()` throws error | ||
* `toAbortable()` handle where getting `[IS_ABORTABLE]` property throws error | ||
* Simplify handling internal then calls? | ||
* `.abort()` called on promise directly unilaterally abort, regardless of number of `.then()` calls | ||
* `.finally` method | ||
|
||
* Deal with case: | ||
|
||
```js | ||
const pInner = new Abortable((resolve, reject, onAbort) => { | ||
onAbort((err) => { | ||
console.log('aborted'); | ||
reject(err); | ||
}); | ||
}); | ||
|
||
let p2, pThen; | ||
const p1 = new Abortable((resolve1) => { | ||
p2 = new Abortable((resolve2) => { | ||
resolve1(pInner); | ||
Promise.resolve().then(() => pThen = pInner.then(v => v)); | ||
resolve2(pInner); | ||
}); | ||
}); | ||
|
||
p1.abort(); | ||
p2.abort(); | ||
pThen.abort(); | ||
// `pInner` should abort at this point, but I think it won't due to `pInner.then()` being wrongly | ||
// identified as an internal `.then()` call | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
/* eslint-disable no-console */ | ||
|
||
'use strict'; | ||
|
||
const Abortable = require('./index.js'); | ||
|
||
let resolve; | ||
const p = Abortable.all([{ | ||
then(_resolve) { | ||
resolve = _resolve; | ||
} | ||
}]); | ||
|
||
(async () => { | ||
await Promise.resolve(); | ||
|
||
let thenGetterCalled = false; | ||
let thenCalled = false; | ||
resolve({ | ||
get then() { | ||
thenGetterCalled = true; | ||
return (r) => { | ||
thenCalled = true; | ||
r(123); | ||
}; | ||
} | ||
}); | ||
|
||
console.log('thenGetterCalled sync:', thenGetterCalled); | ||
console.log('thenCalled sync:', thenCalled); | ||
|
||
await Promise.resolve().then(() => { | ||
console.log('thenCalled after one microtick:', thenCalled); | ||
}); | ||
|
||
const res = await p; | ||
console.log('res:', res); | ||
})(); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,108 @@ | ||
/* -------------------- | ||
* abortable module | ||
* Tests for behavior of native JS Promise | ||
* ------------------*/ | ||
|
||
'use strict'; | ||
|
||
// Imports | ||
const {tick} = require('./support/utils.js'); | ||
|
||
// Init | ||
require('./support/index.js'); | ||
|
||
// Tests | ||
|
||
class PromiseExtended extends Promise { | ||
constructor(executor) { | ||
super(executor || (() => {})); | ||
this.thenCalledTimes = 0; | ||
} | ||
|
||
then() { | ||
this.thenCalledTimes++; | ||
} | ||
} | ||
|
||
describe('Native JS Promise', () => { | ||
describe('calls `.then()` asynchronously on promise passed to `resolve()`', () => { | ||
describe('`resolve()` called synchronously in executor', () => { | ||
it('of native Promise', async () => { | ||
const p = new PromiseExtended(); | ||
new Promise(resolve => resolve(p)); // eslint-disable-line no-new | ||
expect(p.thenCalledTimes).toBe(0); | ||
await tick(); | ||
expect(p.thenCalledTimes).toBe(1); | ||
}); | ||
|
||
it('of extended Promise', async () => { | ||
const p = new PromiseExtended(); | ||
new PromiseExtended(resolve => resolve(p)); // eslint-disable-line no-new | ||
expect(p.thenCalledTimes).toBe(0); | ||
await tick(); | ||
expect(p.thenCalledTimes).toBe(1); | ||
}); | ||
}); | ||
|
||
describe('`resolve()` called synchronously after construction of Promise', () => { | ||
it('of native Promise', async () => { | ||
let resolve; | ||
new Promise((_resolve) => { resolve = _resolve; }); // eslint-disable-line no-new | ||
const p = new PromiseExtended(); | ||
resolve(p); | ||
expect(p.thenCalledTimes).toBe(0); | ||
await tick(); | ||
expect(p.thenCalledTimes).toBe(1); | ||
}); | ||
|
||
it('of extended Promise', async () => { | ||
let resolve; | ||
new PromiseExtended((_resolve) => { resolve = _resolve; }); // eslint-disable-line no-new | ||
const p = new PromiseExtended(); | ||
resolve(p); | ||
expect(p.thenCalledTimes).toBe(0); | ||
await tick(); | ||
expect(p.thenCalledTimes).toBe(1); | ||
}); | ||
}); | ||
|
||
describe('`resolve()` called asynchronously', () => { | ||
it('of native Promise', async () => { | ||
let resolve; | ||
new Promise((_resolve) => { resolve = _resolve; }); // eslint-disable-line no-new | ||
await tick(); | ||
const p = new PromiseExtended(); | ||
resolve(p); | ||
expect(p.thenCalledTimes).toBe(0); | ||
await tick(); | ||
expect(p.thenCalledTimes).toBe(1); | ||
}); | ||
|
||
it('of extended Promise', async () => { | ||
let resolve; | ||
new PromiseExtended((_resolve) => { resolve = _resolve; }); // eslint-disable-line no-new | ||
await tick(); | ||
const p = new PromiseExtended(); | ||
resolve(p); | ||
expect(p.thenCalledTimes).toBe(0); | ||
await tick(); | ||
expect(p.thenCalledTimes).toBe(1); | ||
}); | ||
}); | ||
}); | ||
|
||
// eslint-disable-next-line jest/no-disabled-tests | ||
describe.skip('calls `.then()` asynchronously on promise returned from `.then()` handler', () => { | ||
it('foo', async () => { | ||
let p; | ||
Promise.resolve().then(() => { | ||
p = new PromiseExtended(); | ||
return p; | ||
}); | ||
await tick(); | ||
expect(p.thenCalledTimes).toBe(0); | ||
await tick(); | ||
expect(p.thenCalledTimes).toBe(1); | ||
}); | ||
}); | ||
}); |