Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Expose get and has methods #72

Merged
merged 3 commits into from
Mar 15, 2017
Merged

Expose get and has methods #72

merged 3 commits into from
Mar 15, 2017

Conversation

epayet
Copy link
Contributor

@epayet epayet commented Mar 10, 2017

This has been mentioned in a few issues (#45, #33, #51).

The goal is to expose get and has methods so that we easily have read access to the cache, depending on the arguments.
Hopefully, the tests will demonstrate really well how this works.

I tried to match your coding style, I am happy to take any feedback.
This would be really useful for my use case described here: #33 (comment)

I know you're planning to do a major refactor soon, but in the meantime, I think that exposing those 2 new methods are costless and will be really useful to some people, me included :)

Many thanks.

@medikoo
Copy link
Owner

medikoo commented Mar 10, 2017

Thanks @epayet, at first glance looks good. I'm keen to take it but would prefer to give it a more careful look. If not today, I'll take care of this on Monday.

@epayet
Copy link
Contributor Author

epayet commented Mar 10, 2017

Sure @medikoo thanks for the quick response 👍

@medikoo medikoo self-requested a review March 13, 2017 08:35
@medikoo medikoo self-assigned this Mar 13, 2017
Copy link
Owner

@medikoo medikoo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Additionally there are two lint issues, you can see them by running npm run lint in a project.

Thank you!

var id, args = arguments;
if (resolve) args = resolve(args);
id = get(args);
return conf.has(id);
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's exit early (before conf.has(..)) with false if id resolved to null (It can happen, e.g. https://github.com/medikoo/memoizee/blob/master/normalizers/get-1.js#L10 )

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What you say is true, id can be null. But conf.has(null) always returns false. (hasOwnProperty.call(cache, null) will return false as expected.

I'm not sure we need an extra null check here

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Theoretically we can have 'null' cache id (e.g. with primitive serialization for one argument taking function, the null argument will resolve to 'null' cache id).
And in such case hasOwnProperty.call(cache, null) will result with true, as second argument is in all cases coerced by engine to string:

cache = { 'null': true };
Object.prototype.hasOwnProperty.call(cache, null); // true

id = get(args);
return cache[id];
};
extHas = function () {
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's ensure that extGet and extHas have ensured right lenght, it can be done through defineLength as here -> https://github.com/epayet/memoizee/blob/16601d1d0762d34a844c9916cbe791b34c936aca/lib/configure-map.js#L123

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done 👍

defineProperties(memoized, {
__memoized__: d(true),
delete: d(extDel),
clear: d(conf.clear)
clear: d(conf.clear),
get: d(extGet),
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's expose get as _get (so not as official Public API method). Thing is, that it doesn't work well with async mode, as it will return direct result of asynchronous function, and not asynchronously resolved value, as some may expect.
With v1 (hopefully today I'll post new API proposal) it'll be addressed properly

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I did the renaming for both _has and _get. I did not think of the async mode and this is very important.
As you said I would expect to get the actual value, and not the result of an async function (like a Promise).
I started to write a test for what I would expect, but it is obviously failing because I get a promise back instead of the actual value of it, when resolved.
In the actual state of the library, this seems rather complex to implement now. It will be hopefully addressed on v1 :)

Just to show you what I would expect from it, here is the test case I wrote:

"has & get on Promise mode": function (a, d) {
    var fn = function (x) {
        return new Promise(function (res) {
            setTimeout(function () {
                res(x);
            }, 1);
        });
    }, mfn;
    mfn = memoize(fn, { promise: true });
    a(mfn.has('foo'), false);
    mfn('foo').then(function () {
        // At the moment, we get a solved promise instead of the value
        a(mfn.get('foo'), 'foo');
        a(mfn.has('foo'), true);
        d();
    });
    // Promise is not resolved, yet
    // At the moment, we get true, and an unresolved promise
    a(mfn.has('foo'), false);
    a(mfn.get('foo'), undefined);
},

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, in v1, with get and has, you will always get resolved value, so final value in case of async and promise modes.
I also wrote an updated API proposal already -> #73 (although it doesn't explain that detail)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I like the API proposal, it would be nice to include this behaviour in :)

@medikoo medikoo assigned epayet and unassigned medikoo Mar 13, 2017
Rename methods to _get and _has
Linting
@epayet
Copy link
Contributor Author

epayet commented Mar 14, 2017

I gave it another go according to your requested changes. Can you have a look now and give your feedback?

I left a note on async on another comment, this is an interesting case that I hope will be solved in v1.
In the meantime, if you're happy with this code, it would still be very helpful.

Thanks :)

@medikoo
Copy link
Owner

medikoo commented Mar 14, 2017

@epayet looks great, just check my comment towards null handling :)

@medikoo medikoo self-requested a review March 14, 2017 15:37
@epayet
Copy link
Contributor Author

epayet commented Mar 14, 2017

I added the null check for _has :)
And the build is green 👍

@medikoo medikoo merged commit f1964ca into medikoo:master Mar 15, 2017
@medikoo
Copy link
Owner

medikoo commented Mar 15, 2017

Thank you, published with v0.4.4

@epayet epayet deleted the expose-get-has branch March 15, 2017 17:57
@epayet
Copy link
Contributor Author

epayet commented Mar 16, 2017

Thanks I just checked, it works 👍

@epayet epayet mentioned this pull request Aug 26, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants