@@ -33,6 +33,10 @@ var RCTAsyncStorage = RCTAsyncRocksDBStorage || RCTAsyncSQLiteStorage || RCTAsyn
33
33
* method returns a `Promise` object.
34
34
*/
35
35
var AsyncStorage = {
36
+ _getRequests : ( [ ] : Array < any > ) ,
37
+ _getKeys : ( [ ] : Array < string > ) ,
38
+ _immediate : ( null : ?number ) ,
39
+
36
40
/**
37
41
* Fetches `key` and passes the result to `callback`, along with an `Error` if
38
42
* there is any. Returns a `Promise` object.
@@ -164,6 +168,32 @@ var AsyncStorage = {
164
168
* indicate which key caused the error.
165
169
*/
166
170
171
+ /** Flushes any pending requests using a single multiget */
172
+ flushGetRequests : function ( ) : void {
173
+ const getRequests = this . _getRequests ;
174
+ const getKeys = this . _getKeys ;
175
+
176
+ this . _getRequests = [ ] ;
177
+ this . _getKeys = [ ] ;
178
+
179
+ RCTAsyncStorage . multiGet ( getKeys , function ( errors , result ) {
180
+ // Even though the runtime complexity of this is theoretically worse vs if we used a map,
181
+ // it's much, much faster in practice for the data sets we deal with (we avoid
182
+ // allocating result pair arrays). This was heavily benchmarked.
183
+ const reqLength = getRequests . length ;
184
+ for ( let i = 0 ; i < reqLength ; i ++ ) {
185
+ const request = getRequests [ i ] ;
186
+ const requestKeys = request . keys ;
187
+ var requestResult = result . filter ( function ( resultPair ) {
188
+ return requestKeys . indexOf ( resultPair [ 0 ] ) !== - 1 ;
189
+ } ) ;
190
+
191
+ request . callback && request . callback ( null , requestResult ) ;
192
+ request . resolve && request . resolve ( requestResult ) ;
193
+ }
194
+ } ) ;
195
+ } ,
196
+
167
197
/**
168
198
* multiGet invokes callback with an array of key-value pair arrays that
169
199
* matches the input format of multiSet. Returns a `Promise` object.
@@ -174,17 +204,30 @@ var AsyncStorage = {
174
204
keys : Array < string > ,
175
205
callback ?: ?( errors : ?Array < Error > , result : ?Array < Array < string >> ) => void
176
206
) : Promise {
177
- return new Promise ( ( resolve , reject ) => {
178
- RCTAsyncStorage . multiGet ( keys , function ( errors , result ) {
179
- var error = convertErrors ( errors ) ;
180
- callback && callback ( error , result ) ;
181
- if ( error ) {
182
- reject ( error ) ;
183
- } else {
184
- resolve ( result ) ;
185
- }
207
+ if ( ! this . _immediate ) {
208
+ this . _immediate = setImmediate ( ( ) => {
209
+ this . _immediate = null ;
210
+ this . flushGetRequests ( ) ;
186
211
} ) ;
212
+ }
213
+
214
+ var getRequest = {
215
+ keys : keys ,
216
+ callback : callback ,
217
+ keyIndex : this . _getKeys . length ,
218
+ resolve : null ,
219
+ reject : null ,
220
+ } ;
221
+
222
+ var promiseResult = new Promise ( ( resolve , reject ) => {
223
+ getRequest . resolve = resolve ;
224
+ getRequest . reject = reject ;
187
225
} ) ;
226
+
227
+ this . _getRequests . push ( getRequest ) ;
228
+ this . _getKeys . push . apply ( this . _getKeys , keys ) ;
229
+
230
+ return promiseResult ;
188
231
} ,
189
232
190
233
/**
0 commit comments