Remove every() method (redundant with async.io) and rework demo sample
This commit is contained in:
parent
976330134d
commit
0917763540
29
README.md
29
README.md
@ -1,6 +1,6 @@
|
|||||||
# mhysa
|
# mhysa
|
||||||
|
|
||||||
**Promise, Stream and EventEmitter utils for Node.js**
|
**Streams and event emitter utils for Node.js**
|
||||||
|
|
||||||
## Installation
|
## Installation
|
||||||
|
|
||||||
@ -10,32 +10,29 @@ yarn add mhysa
|
|||||||
|
|
||||||
## Basic Usage
|
## Basic Usage
|
||||||
|
|
||||||
The following snippet demonstrates most of mhysa's current features. More will come!
|
The following snippet demonstrates most of mhysa's current features without much explanation. More
|
||||||
|
will come!
|
||||||
|
|
||||||
```js
|
```js
|
||||||
const { sleep, once, delay, every, stream } = require("mhysa");
|
const { sleep, once, delay, stream } = require("mhysa");
|
||||||
|
|
||||||
async function main() {
|
async function main() {
|
||||||
const collector = stream
|
const collector = stream
|
||||||
.concat(
|
.concat(
|
||||||
stream.fromArray(["a\n", "b\n", "c\n"]),
|
stream.fromArray(["a\n", "b\n", "c\n"]),
|
||||||
stream.fromArray(["d", "e"]).pipe(stream.join("-"))
|
stream.fromArray(["d", "e"]).pipe(stream.join("-")),
|
||||||
)
|
)
|
||||||
.pipe(stream.split("\n"))
|
.pipe(stream.split("\n"))
|
||||||
.pipe(stream.flatMap(s => [s, s.toUpperCase()]))
|
.pipe(
|
||||||
|
stream.flatMap(async s => {
|
||||||
|
await sleep(100);
|
||||||
|
return delay([s, s.toUpperCase()], 100);
|
||||||
|
}),
|
||||||
|
)
|
||||||
.pipe(stream.collect({ objectMode: true }));
|
.pipe(stream.collect({ objectMode: true }));
|
||||||
|
|
||||||
const collected = await once(collector, "data");
|
const collected = await once(collector, "data");
|
||||||
await sleep(1000); // undefined (after one second)
|
console.log(collected); // [ 'a', 'A', 'b', 'B', 'c', 'C', 'd-e', 'D-E' ] (after 12 * 100 ms)
|
||||||
await delay(collected, 1000); // [ 'a', 'A', 'b', 'B', 'c', 'C', 'd-e', 'D-E' ] (after another second)
|
|
||||||
await every(
|
|
||||||
[Promise.resolve("ab"), delay("cd", 1000)],
|
|
||||||
s => s.length === 2
|
|
||||||
); // true (after another second)
|
|
||||||
await every(
|
|
||||||
[Promise.resolve("ab"), delay("cd", 1000)],
|
|
||||||
s => s.length === 1
|
|
||||||
); // false (instantly)
|
|
||||||
}
|
}
|
||||||
main();
|
main();
|
||||||
```
|
```
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "mhysa",
|
"name": "mhysa",
|
||||||
"version": "0.4.1",
|
"version": "0.5.0-beta.0",
|
||||||
"description": "Promise, Stream and EventEmitter utils for Node.js",
|
"description": "Promise, Stream and EventEmitter utils for Node.js",
|
||||||
"keywords": [
|
"keywords": [
|
||||||
"promise",
|
"promise",
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
const { sleep, once, delay, every, stream } = require("mhysa");
|
const { sleep, once, delay, stream } = require("mhysa");
|
||||||
|
|
||||||
async function main() {
|
async function main() {
|
||||||
const collector = stream
|
const collector = stream
|
||||||
@ -7,19 +7,15 @@ async function main() {
|
|||||||
stream.fromArray(["d", "e"]).pipe(stream.join("-")),
|
stream.fromArray(["d", "e"]).pipe(stream.join("-")),
|
||||||
)
|
)
|
||||||
.pipe(stream.split("\n"))
|
.pipe(stream.split("\n"))
|
||||||
.pipe(stream.flatMap(s => [s, s.toUpperCase()]))
|
.pipe(
|
||||||
|
stream.flatMap(async s => {
|
||||||
|
await sleep(100);
|
||||||
|
return delay([s, s.toUpperCase()], 100);
|
||||||
|
}),
|
||||||
|
)
|
||||||
.pipe(stream.collect({ objectMode: true }));
|
.pipe(stream.collect({ objectMode: true }));
|
||||||
|
|
||||||
const collected = await once(collector, "data");
|
const collected = await once(collector, "data");
|
||||||
await sleep(1000); // undefined (after one second)
|
console.log(collected); // [ 'a', 'A', 'b', 'B', 'c', 'C', 'd-e', 'D-E' ] (after 6 * 100 ms)
|
||||||
console.log(await delay(collected, 1000)); // [ 'a', 'A', 'b', 'B', 'c', 'C', 'd-e', 'D-E' ] (after another second)
|
|
||||||
await every(
|
|
||||||
[Promise.resolve("ab"), delay("cd", 1000)],
|
|
||||||
s => s.length === 2,
|
|
||||||
); // true (after another second)
|
|
||||||
await every(
|
|
||||||
[Promise.resolve("ab"), delay("cd", 1000)],
|
|
||||||
s => s.length === 1,
|
|
||||||
); // false (instantly)
|
|
||||||
}
|
}
|
||||||
main();
|
main();
|
||||||
|
@ -37,44 +37,3 @@ test("once() resolves only after the specified event is emitted", async t => {
|
|||||||
expect(after - before).gte(200);
|
expect(after - before).gte(200);
|
||||||
expect(after - before).closeTo(200, TimingErrorMarginMs);
|
expect(after - before).closeTo(200, TimingErrorMarginMs);
|
||||||
});
|
});
|
||||||
|
|
||||||
test("every() resolves to true when the predicate holds true for all resolved values", async t => {
|
|
||||||
const before = Date.now();
|
|
||||||
const result = await every(
|
|
||||||
[Promise.resolve("a"), Promise.resolve("b"), delay("c", 200)],
|
|
||||||
() => true,
|
|
||||||
);
|
|
||||||
const after = Date.now();
|
|
||||||
expect(result).equal(true);
|
|
||||||
expect(after - before).gte(200);
|
|
||||||
expect(after - before).closeTo(200, TimingErrorMarginMs);
|
|
||||||
});
|
|
||||||
|
|
||||||
test("every() resolves to false as soon as the predicate does not hold for some resolved value", async t => {
|
|
||||||
const before = Date.now();
|
|
||||||
const result = await every(
|
|
||||||
[Promise.resolve("a"), Promise.resolve("bb"), delay("c", 200)],
|
|
||||||
(value: string) => value.length === 1,
|
|
||||||
);
|
|
||||||
const after = Date.now();
|
|
||||||
expect(result).equal(false);
|
|
||||||
expect(after - before).lt(200);
|
|
||||||
expect(after - before).closeTo(0, TimingErrorMarginMs);
|
|
||||||
});
|
|
||||||
|
|
||||||
test("every() rejects with the reason as soon as any of the promises rejects", async t => {
|
|
||||||
const before = Date.now();
|
|
||||||
await t.throwsAsync(() =>
|
|
||||||
every(
|
|
||||||
[
|
|
||||||
Promise.resolve("a"),
|
|
||||||
Promise.reject(new Error("Expected")),
|
|
||||||
delay("c", 200),
|
|
||||||
],
|
|
||||||
() => true,
|
|
||||||
),
|
|
||||||
);
|
|
||||||
const after = Date.now();
|
|
||||||
expect(after - before).lt(200);
|
|
||||||
expect(after - before).closeTo(0, TimingErrorMarginMs);
|
|
||||||
});
|
|
||||||
|
45
src/utils.ts
45
src/utils.ts
@ -37,48 +37,3 @@ export function once<T>(
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Eagerly resolve to false as soon as any of the promises has resolved to a value for which the
|
|
||||||
* predicate is falsey, or resolve to true when all of the promises have resolved to a value for which
|
|
||||||
* the predicate is thruthy, or rejects with the reason of the first promise rejection
|
|
||||||
*
|
|
||||||
* @param promises Promises whose resolved values will be tested by the predicate
|
|
||||||
* @param predicate Predicate to apply
|
|
||||||
* @returns Promise indicating whether the predicate holds for all resolved promise values
|
|
||||||
*/
|
|
||||||
export function every<T>(
|
|
||||||
promises: Array<Promise<T>>,
|
|
||||||
predicate: (value: T) => boolean,
|
|
||||||
): Promise<boolean> {
|
|
||||||
if (promises.length > 0) {
|
|
||||||
return new Promise((resolve, reject) => {
|
|
||||||
let resolvedCount = 0;
|
|
||||||
let done = false;
|
|
||||||
promises.forEach(promise => {
|
|
||||||
promise
|
|
||||||
.then(value => {
|
|
||||||
resolvedCount++;
|
|
||||||
if (!done) {
|
|
||||||
const predicateValue = predicate(value);
|
|
||||||
if (!predicateValue) {
|
|
||||||
resolve(false);
|
|
||||||
done = true;
|
|
||||||
} else if (resolvedCount === promises.length) {
|
|
||||||
resolve(predicateValue);
|
|
||||||
done = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.catch(err => {
|
|
||||||
if (!done) {
|
|
||||||
reject(err);
|
|
||||||
done = true;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
return Promise.resolve(true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
Loading…
Reference in New Issue
Block a user