Você não pode selecionar mais de 25 tópicos Os tópicos devem começar com uma letra ou um número, podem incluir traços ('-') e podem ter até 35 caracteres.

Storage.js 4.9KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
  1. import { AsyncStorage } from 'react-native';
  2. /**
  3. * A Web Sorage API implementation used for polyfilling
  4. * {@code window.localStorage} and/or {@code window.sessionStorage}.
  5. * <p>
  6. * The Web Storage API is synchronous whereas React Native's builtin generic
  7. * storage API {@code AsyncStorage} is asynchronous so the implementation with
  8. * persistence is optimistic: it will first store the value locally in memory so
  9. * that results can be served synchronously and then persist the value
  10. * asynchronously. If an asynchronous operation produces an error, it's ignored.
  11. */
  12. export default class Storage {
  13. /**
  14. * Initializes a new {@code Storage} instance. Loads all previously
  15. * persisted data items from React Native's {@code AsyncStorage} if
  16. * necessary.
  17. *
  18. * @param {string|undefined} keyPrefix - The prefix of the
  19. * {@code AsyncStorage} keys to be persisted by this storage.
  20. */
  21. constructor(keyPrefix) {
  22. /**
  23. * The prefix of the {@code AsyncStorage} keys persisted by this
  24. * storage. If {@code undefined}, then the data items stored in this
  25. * storage will not be persisted.
  26. *
  27. * @private
  28. * @type {string}
  29. */
  30. this._keyPrefix = keyPrefix;
  31. if (typeof this._keyPrefix !== 'undefined') {
  32. // Load all previously persisted data items from React Native's
  33. // AsyncStorage.
  34. AsyncStorage.getAllKeys().then((...getAllKeysCallbackArgs) => {
  35. // XXX The keys argument of getAllKeys' callback may or may not
  36. // be preceded by an error argument.
  37. const keys
  38. = getAllKeysCallbackArgs[getAllKeysCallbackArgs.length - 1]
  39. .filter(key => key.startsWith(this._keyPrefix));
  40. AsyncStorage.multiGet(keys).then((...multiGetCallbackArgs) => {
  41. // XXX The result argument of multiGet may or may not be
  42. // preceded by an errors argument.
  43. const result
  44. = multiGetCallbackArgs[multiGetCallbackArgs.length - 1];
  45. const keyPrefixLength
  46. = this._keyPrefix && this._keyPrefix.length;
  47. // eslint-disable-next-line prefer-const
  48. for (let [ key, value ] of result) {
  49. key = key.substring(keyPrefixLength);
  50. // XXX The loading of the previously persisted data
  51. // items from AsyncStorage is asynchronous which means
  52. // that it is technically possible to invoke setItem
  53. // with a key before the key is loaded from
  54. // AsyncStorage.
  55. if (!this.hasOwnProperty(key)) {
  56. this[key] = value;
  57. }
  58. }
  59. });
  60. });
  61. }
  62. }
  63. /**
  64. * Removes all keys from this storage.
  65. *
  66. * @returns {void}
  67. */
  68. clear() {
  69. for (const key of Object.keys(this)) {
  70. this.removeItem(key);
  71. }
  72. }
  73. /**
  74. * Returns the value associated with a specific key in this storage.
  75. *
  76. * @param {string} key - The name of the key to retrieve the value of.
  77. * @returns {string|null} The value associated with {@code key} or
  78. * {@code null}.
  79. */
  80. getItem(key) {
  81. return this.hasOwnProperty(key) ? this[key] : null;
  82. }
  83. /**
  84. * Returns the name of the nth key in this storage.
  85. *
  86. * @param {number} n - The zero-based integer index of the key to get the
  87. * name of.
  88. * @returns {string} The name of the nth key in this storage.
  89. */
  90. key(n) {
  91. const keys = Object.keys(this);
  92. return n < keys.length ? keys[n] : null;
  93. }
  94. /**
  95. * Returns an integer representing the number of data items stored in this
  96. * storage.
  97. *
  98. * @returns {number}
  99. */
  100. get length() {
  101. return Object.keys(this).length;
  102. }
  103. /**
  104. * Removes a specific key from this storage.
  105. *
  106. * @param {string} key - The name of the key to remove.
  107. * @returns {void}
  108. */
  109. removeItem(key) {
  110. delete this[key];
  111. typeof this._keyPrefix === 'undefined'
  112. || AsyncStorage.removeItem(`${String(this._keyPrefix)}${key}`);
  113. }
  114. /**
  115. * Adds a specific key to this storage and associates it with a specific
  116. * value. If the key exists already, updates its value.
  117. *
  118. * @param {string} key - The name of the key to add/update.
  119. * @param {string} value - The value to associate with {@code key}.
  120. * @returns {void}
  121. */
  122. setItem(key, value) {
  123. value = String(value); // eslint-disable-line no-param-reassign
  124. this[key] = value;
  125. typeof this._keyPrefix === 'undefined'
  126. || AsyncStorage.setItem(`${String(this._keyPrefix)}${key}`, value);
  127. }
  128. }