Skip to content

Commit

Permalink
Merge pull request #53 from GrosSacASac/refactor
Browse files Browse the repository at this point in the history
Refactor
  • Loading branch information
GrosSacASac authored Dec 21, 2020
2 parents 6aedec6 + 5e780fa commit 8d89cd0
Show file tree
Hide file tree
Showing 7 changed files with 98 additions and 46 deletions.
5 changes: 5 additions & 0 deletions changelog.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
# Changelog

## 14.0.0

* memoizeAsStrings requires Map support
* chainPromiseNTimes handles rejection like Promise.all

## 13.1.0

* How to import in deno examples
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "utilsac",
"version": "13.1.0",
"version": "14.0.0",
"description": "Utility functions",
"license": "CC0-1.0",
"type": "module",
Expand Down
7 changes: 5 additions & 2 deletions tests/debugging_reproduction/deepDiffSlow.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import {deepDifference} from "../../deep.js";

deepDifference([
const result = deepDifference([
[
0,
0,
Expand Down Expand Up @@ -5202,4 +5202,7 @@ deepDifference([
0,
0,
],
]).changes;
]);

console.log(result);

4 changes: 2 additions & 2 deletions tests/performance/deepCopy.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,15 +25,15 @@ let b; // eslint-disable-line
const JSONCopyTest = {
name: `JSONCopy`,
code: (shared, finish) => {
b = deepCopyJSON(a);
b = deepCopyJSON(a); // eslint-disable-line
finish();
},
};

const deepCopyTest = {
name: `deepCopy`,
code: (shared, finish) => {
b = deepCopy(a);
b = deepCopy(a); // eslint-disable-line
finish();
},
};
Expand Down
32 changes: 32 additions & 0 deletions tests/specification/chainPromiseNTimes.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import test from "ava";
import { chainPromiseNTimes } from "../../utility.js";


const resolveValue = {};
const promiseCreator = () => {
return Promise.resolve(resolveValue);
};
const rejectValue = `error`;
const rejectingPromiseCreator = () => {
return Promise.reject(rejectValue);
};

test(`chainPromiseNTimes returns a promise`, t => {
t.is(typeof chainPromiseNTimes(promiseCreator, 1).then, `function`);
});

test(`chainPromiseNTimes resolves with values Array`, async t => {
return chainPromiseNTimes(promiseCreator, 2).then(values => {
t.truthy(Array.isArray(values));
values.forEach(value => {
t.is(value, resolveValue);
});
});
});

test(`chainPromiseNTimes reject with first rejecting value`, async t => {
return chainPromiseNTimes(rejectingPromiseCreator, 3).then(() => {
}).catch(error => {
t.is(error, rejectValue);
});
});
36 changes: 36 additions & 0 deletions tests/specification/chainPromises.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import test from "ava";
import { chainPromises } from "../../utility.js";


const resolveValue = {};
const promiseCreator = () => {
return Promise.resolve(resolveValue);
};
const rejectValue = `error`;
const rejectingPromiseCreator = () => {
return Promise.reject(rejectValue);
};

test(`chainPromises returns a promise`, t => {
t.is(typeof chainPromises([promiseCreator]).then, `function`);
});

test(`chainPromises resolves with values Array`, async t => {
return chainPromises([promiseCreator, promiseCreator]).then(values => {
t.truthy(Array.isArray(values));
values.forEach(value => {
t.is(value, resolveValue);
});
});
});

test(`chainPromises reject with first rejecting value`, async t => {
return chainPromises([
promiseCreator,
rejectingPromiseCreator,
promiseCreator,
]).then(() => {
}).catch(error => {
t.is(error, rejectValue);
});
});
58 changes: 17 additions & 41 deletions utility.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,9 @@ export {
bytesLengthFromString,
};

const waitTimeDefault = 150;
const timeDefault = 150;

const createDebounced = function (functionToDebounce, waitTime = waitTimeDefault) {
const createDebounced = function (functionToDebounce, waitTime = timeDefault) {
/* creates a function that is de-bounced,
calling it, will eventually execute it, when you stop calling it
useful for scroll events, resize, search etc
Expand All @@ -34,9 +34,7 @@ const createDebounced = function (functionToDebounce, waitTime = waitTimeDefault
};
};

const minimumTimeSpaceDefault = 150;

const createThrottled = function (functionToThrottle, minimumTimeSpace = minimumTimeSpaceDefault) {
const createThrottled = function (functionToThrottle, minimumTimeSpace = timeDefault) {
/* creates a function that is throttled,
calling it once will execute it immediately
calling it very often during a period less than minimumTimeSpace will only execute it once
Expand All @@ -53,8 +51,7 @@ const createThrottled = function (functionToThrottle, minimumTimeSpace = minimum
};
};


const throttledWithLast = function (functionToThrottle, minimumTimeSpace = minimumTimeSpaceDefault, waitTime = waitTimeDefault) {
const throttledWithLast = function (functionToThrottle, minimumTimeSpace = timeDefault, waitTime = timeDefault) {
/* creates a function that is throttled,
calling it once will execute it immediately
calling it very often during a period less than minimumTimeSpace will only execute it twice:
Expand Down Expand Up @@ -105,9 +102,7 @@ const chainPromises = function (promiseCreators) {
values.push(value);
}
if (i < length) {
const promise = promiseCreators[i]();
promise.then(chainer);
promise.catch(reject);
promiseCreators[i]().then(chainer).catch(reject);
} else {
resolve(values);
}
Expand All @@ -116,6 +111,14 @@ const chainPromises = function (promiseCreators) {
});
};

const chainPromiseNTimes = function (promiseCreator, times) {
/* different than Promise.all
only executes promiseCreator one after the previous has resolved
useful for testing
resolves with an array of values */
return chainPromises(Array.from({length: times}).fill(promiseCreator));
};

const chainRequestAnimationFrame = function (functions) {
return new Promise(function (resolve, reject) {
const values = [];
Expand All @@ -139,33 +142,6 @@ const chainRequestAnimationFrame = function (functions) {
});
};

const chainPromiseNTimes = function (promiseCreator, times) {
/* different than Promise.all
only executes promiseCreator one after the previous has resolved
useful for testing
resolves with an array of values
could be made with chainPromises, but chose not to
to avoid an adapter array */
const values = [];
if (times === 0) {
return Promise.resolve(values);
}
return new Promise(function (resolve) {
let i = 0;
const chainer = function (value) {
i += 1;
values.push(value);
if (i < times) {
promiseCreator().then(chainer);
return;
}
resolve(values);
};
promiseCreator().then(chainer);
});
};

const timeFunction = function (callback, timer = Date) {
// executes callback and returns time elapsed in ms
const startTime = timer.now();
Expand Down Expand Up @@ -195,18 +171,18 @@ const memoizeAsStrings = function (functionToMemoize, separator = `-`) {
fast memoizer
but infinitely growing */

const previousResults = {};
const previousResults = new Map();
return function (...args) {
const argumentsAsStrings = args.map(String).join(separator);
/*
without .map(String) works but undefined and null become empty strings
const argumentsAsStrings = args.join(separator);
*/
if (!Object.prototype.hasOwnProperty.call(previousResults, argumentsAsStrings)) {
if (!previousResults.has(argumentsAsStrings)) {
// not yet in cache
previousResults[argumentsAsStrings] = functionToMemoize(...args);
previousResults.set(argumentsAsStrings, functionToMemoize(...args));
}
return previousResults[argumentsAsStrings];
return previousResults.get(argumentsAsStrings);
};
};

Expand Down

0 comments on commit 8d89cd0

Please sign in to comment.