Lifecycle of methods
Understanding this will help understanding how plugins work and how to write them.
Methods available after creating an instance of cache (see cacheInstance): buildKey, getItem, getExtra, setItem, hasItem and removeItem, have certain lifecycle.
This is how it looks like 'inside':
{
// (1)
method(arg) {
// (2)
const preData = getPreData('eventName', { arg, cacheInstance: this });
// (3)
const result = adapter.method(preData.arg);
// (4)
const postData = getPostData('eventName', { arg: preData.arg, result, cacheInstance: preData.cacheInstance });
// (5)
return postData.result;
}
}
Here's what is happening:
- Given method is called with argument(s) passed to it.
preDatais being fetched, which stands forget me data for 'pre' lifecycle part of this method, for event 'eventName' with those arguments.- Adapter's method is being called with
argreturned bygetPreData. postDatais being fetched, which stands forget me data for 'post' lifecycle part of this method, for event 'eventName' with those arguments.resultthat came back from adapter and was passed throughgetPostDatais being returned finally by this method.
Now, let's use getItem method and inspect this in more detail:
// this is an instance of cache
{
// (1)
getItem(key) {
// (2)
const preData = getPreData('getItem', { cacheInstance: this, key });
// (3)
const item = adapter.getItem(this.buildKey(preData.key));
// (4)
const postData = getPostData('getItem', { cacheInstance: preData.cacheInstance, key: preData.key, item });
// (5)
return postData.item;
}
}
- cache instance's
getItem(key)method is called, takes akeyas an argument. Depending on method used, there can be more arguments (e.g. setItem(key, value, [extra])). preDatais fetched. There are few things to remember, as there is a pattern here:all methods (ones mentioned at the beginning) have event name passed as a string of value equal to that method's name. So, for example
hasItem(key)method will have'hasItem'string passed, orremoveItem(key)will have'removeItem'passed,getPreDatawill construct a full event name; here, forpredata, event name will be'preGetItem'(camelCase); so, forhasItem(key)it will be'preHasItem'and so on,object being passed alongside event name always contains
cacheInstancewhich is a reference tothiswhich is cache instance itself; this is useful if any plugin will need to use cache's method - be careful with that, as it gives you much power, so be responsible,the same object, for
preDatawill always have the very same properties as arguments passed to called function (alongsidecacheInstance), herekey; for examplehasItem(key)will pass onlykeyandcacheInstancebutsetItem(key, value, [extra])will passkey,value,extraandcacheInstanceproperties (extra defaults to empty object if not passed).Checkout all methods in cacheInstance for detailed description what is passed at this point.
Returned
preData(an object) will contain the very same properties, but values of those properties might be different.Why?
If there are hooks added for given event (here
'preGetItem') and handlers (for those events) mutate the data (e.g. add prefix for the key or something else), then that mutated data is returned.
If there are no hooks added for that event, data is returned without any changes.So, here, for
getItemmethodpreDatawill havekeyandcacheInstanceproperty. There can be additional properties added (by mentioned handlers), but those two will be there always.Adapter's method is being called, fetching item from storage. There are few things to mention here:
for all methods (except for
buildKey) key is being built using cache'sbuildKeymethod (hencethis.buildKey(preData.key),key is being built using key value returned in
preData, not key passed togetItemmethod.
postDatais fetched. There are few things to remember, as there is a pattern here as well:all methods (ones mentioned at the beginning) have event name passed as a string of value equal to that method's name. So, for example
hasItem(key)method will have'hasItem'string passed, orremoveItem(key)will have'removeItem'passed,getPostDatawill construct a full event name; here, forpostdata, event name will be'postGetItem'(camelCase); so, forhasItem(key)it will be'postHasItem'and so on,object being passed alongside event name always contains
cacheInstancewhich is a reference tothiswhich is cache instance itself, but this time it's the one returned inpreData; this is useful if any plugin will need to use cache's method - be careful with that, as it gives you much power, so be responsible,the same object, for
postDatawill always have the very same properties as arguments passed to called function (alongsidecacheInstance), herekey, but also value returned by adapter, and there is a bit difference to what has happened inprephase: each method (might) pass some additional property. Checkout all methods in cacheInstance for detailed description what is passed at this point.
Returned
postData(an object) will contain the very same properties, but values of those properties might be different.Why?
If there are hooks added for given event (here
'postGetItem') and handlers (for those events) mutate the data (e.g. increment counter how many times item was fetched from cache), then that mutated data is returned.
If there are no hooks added for that event, data is returned without any changes.So, here, for
getItemmethodpostDatawill havekey,itemandcacheInstanceproperty. There can be additional properties added (by mentioned handlers), but those three will be there always.Finally,
itemis returned, one stored inpreData, not one returned directly by adapter.
And that's it.
For more details about what is passed and retrieved for all methods and their lifecycle parts, checkout cacheInstance's API docs.