How to implement a DAO library that supports expiration time with native Javascript
Today, I will talk to you about how native Javascript implements a DAO library that supports expiration time. Many people may not know much about it. In order to make you understand better, the editor has summarized the following for you. I hope you can get something according to this article.
Mainly to solve the problem of native localStorage can not set the expiration time, and through encapsulation, to achieve a convenient and powerful localStorage library, on the library encapsulation of some basic ideas and patterns, I will use the previous writing how to use less than 200 lines of code to write their own js class library in a similar method.
Design ideas
We will extend it based on localStorage's original api to support expiration time and callback after the operation is completed. At the end of the article, I will give the completion code of the library, and then we will implement it step by step.
Text
First, let's design the basic framework of the library:
Const BaseStorage = function (preId, timeSign) {/ / initialize some operations} BaseStorage.prototype = {storage: localStorage | | window.localStorage, set: function (key, value, cb, time) {}, get: function (key, cb) {}, / / delete storage. If deleted successfully, return the deleted content remove: function (key, cb) {}}
As you can see above, our storage will have three core api, namely set,get,remove. We use localStorage as the basic library support. Of course, you can also replace the above library with sessionStorage or other.
With the basic skeleton, we can achieve the encapsulation of basic functions. Here, we first add an attribute to the prototype to list the states in the data operation.
Status: {SUCCESS: 0, / / successful FAILURE: 1, / / failed OVERFLOW: 2, / / data overflow TIMEOUT: 3 / / timeout}
In order to achieve expiration time, we have two ways of thinking. The first is to save an expiration time in storage and check whether it expires for each operation, but this scheme means that different keys have to set different expiration time storage corresponding to it, which will take up extra library memory and is not convenient to maintain. Another method is to store the expiration time in the key value, separate the time and the value by an identifier, intercept the expiration time from the value each time, and then return the real value. This scheme does not add additional key-value pairs to store, and is relatively easy to maintain, so we adopt this scheme. To distinguish between different library objects, we can also add key prefixes as follows:
Const BaseLocalStorage = function (preId, timeSign) {this.preId = preId; / / key prefix this.timeSign = timeSign | |'|-|; / / delimiter of expiration time and value}
Based on this idea, we can realize the following.
The way getKey-- modifies key does not affect users' influence on real key
GetKey: function (key) {return this.preId + key}
Set implementation
Set: function (key, value, cb, time) {var status = this.status.SUCCESS, key = this.getKey (key); / / set expiration time. Default is one month try {time = new Date (time). GetTime () | time.getTime () } catch (e) {time = new Date (). GetTime () + 1000 "60" 60 "24" 31} try {this.storage.setItem (key, time + this.timeSign + value);} catch (e) {status = this.status.OVERFLOW;} / / callback cb & & cb.call (this, status, key, value)}
Get implementation
Get: function (key, cb) {var status = this.status.SUCCESS, key = this.getKey (key), value = null, timeSignLen = this.timeSign.length, that = this, index, time, result; try {value = that.storage.getItem (key) } catch (e) {result = {status: that.status.FAILURE, value: null} cb & & cb.call (this, result.status, result.value); return result} if (value) {index = value.indexOf (that.timeSign); time = + value.slice (0, index) / / determine whether it expires, clear if (time > new Date (). GetTime () | | time = = 0) {value = value.slice (index+timeSignLen);} else {value = null, status = that.status.TIMEOUT; that.remove (key);}} else {status = that.status.FAILURE } result = {status: status, value: value}; cb & & cb.call (this, result.status, result.value); return result}
Remove implementation
/ / delete storage. If deleted successfully, return the deleted content remove: function (key, cb) {var status = this.status.FAILURE, key = this.getKey (key), value = null; try {value = this.storage.getItem (key);} catch (e) {/ / dosomething} if (value) {try {this.storage.removeItem (key) Status = this.status.SUCCESS;} catch (e) {/ / dosomething}} cb & & cb.call (this, status, status > 0? Null: value.slice (value.indexOf (this.timeSign) + this.timeSign.length))}
In the implementation of api, because some misoperation is likely to cause storage to report an error, it is recommended to wrap it in trycatch so as to avoid affecting the logic behind.
Then we can use it like this:
Let a = new BaseStorage ('_','@'); a.set ('name',' 123') a.get ('name') / / {status: 0, value: "123"} / / set failure time a.set (' name', '123, null, new Date (). GetTime () + 1000 "60" 60 "24" 31) / / remove a.remove (' name')
Complete source code
/ * data Manager * / (function (win) {const BaseStorage = function (preId, timeSign) {this.preId = preId; this.timeSign = timeSign |'|-|' } BaseStorage.prototype = {status: {SUCCESS: 0, FAILURE: 1, OVERFLOW: 2, TIMEOUT: 3}, storage: localStorage | | window.localStorage, getKey: function (key) {return this.preId + key}, set: function (key, value, cb, time) {var status = this.status.SUCCESS, key = this.getKey (key) / / set the failure time, which defaults to one month try {time = new Date (time). GetTime () | | time.getTime ();} catch (e) {time = new Date (). GetTime () + 1000 "60" 60 "24" 31} try {this.storage.setItem (key, time + this.timeSign + value) } catch (e) {status = this.status.OVERFLOW;} cb & & cb.call (this, status, key, value)}, get: function (key, cb) {var status = this.status.SUCCESS, key = this.getKey (key), value = null, timeSignLen = this.timeSign.length, that = this, index, time, result Try {value = that.storage.getItem (key);} catch (e) {result = {status: that.status.FAILURE, value: null} cb & & cb.call (this, result.status, result.value); return result} if (value) {index = value.indexOf (that.timeSign) Time = + value.slice (0, index); if (time > new Date (). GetTime () | | time = = 0) {value = value.slice (index+timeSignLen);} else {value = null, status = that.status.TIMEOUT; that.remove (key);}} else {status = that.status.FAILURE } result = {status: status, value: value}; cb & & cb.call (this, result.status, result.value); return result}, / / delete storage. If deleted successfully, return the deleted content remove: function (key, cb) {var status = this.status.FAILURE, key = this.getKey (key), value = null Try {value = this.storage.getItem (key);} catch (e) {/ / dosomething} if (value) {try {this.storage.removeItem (key); status = this.status.SUCCESS;} catch (e) {/ / dosomething}} cb & & cb.call (this, status, status > 0? Null: value.slice (value.indexOf (this.timeSign) + this.timeSign.length)}} win.BS = BaseStorage;}) (window)
After reading the above, do you have any further understanding of how native Javascript implements a DAO library that supports expiration? If you want to know more knowledge or related content, please follow the industry information channel, thank you for your support.