From 0917763540332822599b7c922bc16d24d6ba8311 Mon Sep 17 00:00:00 2001 From: Sami Turcotte Date: Wed, 28 Nov 2018 23:44:59 -0500 Subject: [PATCH] Remove every() method (redundant with async.io) and rework demo sample --- README.md | 29 +++++++++++++---------------- package.json | 2 +- samples/demo.js | 20 ++++++++------------ src/utils.spec.ts | 41 ----------------------------------------- src/utils.ts | 45 --------------------------------------------- 5 files changed, 22 insertions(+), 115 deletions(-) diff --git a/README.md b/README.md index a8934ae..aad0b12 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # mhysa -**Promise, Stream and EventEmitter utils for Node.js** +**Streams and event emitter utils for Node.js** ## Installation @@ -10,32 +10,29 @@ yarn add mhysa ## 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 -const { sleep, once, delay, every, stream } = require("mhysa"); +const { sleep, once, delay, stream } = require("mhysa"); async function main() { const collector = stream .concat( - stream.fromArray(["a\n", "b\n", "c\n"]), - stream.fromArray(["d", "e"]).pipe(stream.join("-")) + stream.fromArray(["a\n", "b\n", "c\n"]), + stream.fromArray(["d", "e"]).pipe(stream.join("-")), ) .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 })); const collected = await once(collector, "data"); - await sleep(1000); // undefined (after one second) - 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) + console.log(collected); // [ 'a', 'A', 'b', 'B', 'c', 'C', 'd-e', 'D-E' ] (after 12 * 100 ms) } main(); ``` diff --git a/package.json b/package.json index 5b231ec..3173cd8 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "mhysa", - "version": "0.4.1", + "version": "0.5.0-beta.0", "description": "Promise, Stream and EventEmitter utils for Node.js", "keywords": [ "promise", diff --git a/samples/demo.js b/samples/demo.js index c418787..4bfbb3e 100644 --- a/samples/demo.js +++ b/samples/demo.js @@ -1,4 +1,4 @@ -const { sleep, once, delay, every, stream } = require("mhysa"); +const { sleep, once, delay, stream } = require("mhysa"); async function main() { const collector = stream @@ -7,19 +7,15 @@ async function main() { stream.fromArray(["d", "e"]).pipe(stream.join("-")), ) .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 })); const collected = await once(collector, "data"); - await sleep(1000); // undefined (after one second) - 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) + console.log(collected); // [ 'a', 'A', 'b', 'B', 'c', 'C', 'd-e', 'D-E' ] (after 6 * 100 ms) } main(); diff --git a/src/utils.spec.ts b/src/utils.spec.ts index 9146126..8a89117 100644 --- a/src/utils.spec.ts +++ b/src/utils.spec.ts @@ -37,44 +37,3 @@ test("once() resolves only after the specified event is emitted", async t => { expect(after - before).gte(200); 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); -}); diff --git a/src/utils.ts b/src/utils.ts index 31fc3d8..4fbca59 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -37,48 +37,3 @@ export function once( }); }); } - -/** - * 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( - promises: Array>, - predicate: (value: T) => boolean, -): Promise { - 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); - } -}