mirror of
https://github.com/status-im/react-native.git
synced 2025-01-15 20:15:11 +00:00
Batch AsyncStorage.multiGet calls
Reviewed By: javache Differential Revision: D2636553 fb-gh-sync-id: d6351b67c615d8c01c11c10e32321a9764c54c67
This commit is contained in:
parent
3313f769f5
commit
a64ee7d8c5
@ -33,6 +33,10 @@ var RCTAsyncStorage = RCTAsyncRocksDBStorage || RCTAsyncSQLiteStorage || RCTAsyn
|
|||||||
* method returns a `Promise` object.
|
* method returns a `Promise` object.
|
||||||
*/
|
*/
|
||||||
var AsyncStorage = {
|
var AsyncStorage = {
|
||||||
|
_getRequests: ([]: Array<any>),
|
||||||
|
_getKeys: ([]: Array<string>),
|
||||||
|
_immediate: (null: ?number),
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Fetches `key` and passes the result to `callback`, along with an `Error` if
|
* Fetches `key` and passes the result to `callback`, along with an `Error` if
|
||||||
* there is any. Returns a `Promise` object.
|
* there is any. Returns a `Promise` object.
|
||||||
@ -164,6 +168,32 @@ var AsyncStorage = {
|
|||||||
* indicate which key caused the error.
|
* indicate which key caused the error.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/** Flushes any pending requests using a single multiget */
|
||||||
|
flushGetRequests: function(): void {
|
||||||
|
const getRequests = this._getRequests;
|
||||||
|
const getKeys = this._getKeys;
|
||||||
|
|
||||||
|
this._getRequests = [];
|
||||||
|
this._getKeys = [];
|
||||||
|
|
||||||
|
RCTAsyncStorage.multiGet(getKeys, function(errors, result) {
|
||||||
|
// Even though the runtime complexity of this is theoretically worse vs if we used a map,
|
||||||
|
// it's much, much faster in practice for the data sets we deal with (we avoid
|
||||||
|
// allocating result pair arrays). This was heavily benchmarked.
|
||||||
|
const reqLength = getRequests.length;
|
||||||
|
for (let i = 0; i < reqLength; i++) {
|
||||||
|
const request = getRequests[i];
|
||||||
|
const requestKeys = request.keys;
|
||||||
|
var requestResult = result.filter(function(resultPair) {
|
||||||
|
return requestKeys.indexOf(resultPair[0]) !== -1;
|
||||||
|
});
|
||||||
|
|
||||||
|
request.callback && request.callback(null, requestResult);
|
||||||
|
request.resolve && request.resolve(requestResult);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* multiGet invokes callback with an array of key-value pair arrays that
|
* multiGet invokes callback with an array of key-value pair arrays that
|
||||||
* matches the input format of multiSet. Returns a `Promise` object.
|
* matches the input format of multiSet. Returns a `Promise` object.
|
||||||
@ -174,17 +204,30 @@ var AsyncStorage = {
|
|||||||
keys: Array<string>,
|
keys: Array<string>,
|
||||||
callback?: ?(errors: ?Array<Error>, result: ?Array<Array<string>>) => void
|
callback?: ?(errors: ?Array<Error>, result: ?Array<Array<string>>) => void
|
||||||
): Promise {
|
): Promise {
|
||||||
return new Promise((resolve, reject) => {
|
if (!this._immediate) {
|
||||||
RCTAsyncStorage.multiGet(keys, function(errors, result) {
|
this._immediate = setImmediate(() => {
|
||||||
var error = convertErrors(errors);
|
this._immediate = null;
|
||||||
callback && callback(error, result);
|
this.flushGetRequests();
|
||||||
if (error) {
|
|
||||||
reject(error);
|
|
||||||
} else {
|
|
||||||
resolve(result);
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
var getRequest = {
|
||||||
|
keys: keys,
|
||||||
|
callback: callback,
|
||||||
|
keyIndex: this._getKeys.length,
|
||||||
|
resolve: null,
|
||||||
|
reject: null,
|
||||||
|
};
|
||||||
|
|
||||||
|
var promiseResult = new Promise((resolve, reject) => {
|
||||||
|
getRequest.resolve = resolve;
|
||||||
|
getRequest.reject = reject;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
this._getRequests.push(getRequest);
|
||||||
|
this._getKeys.push.apply(this._getKeys, keys);
|
||||||
|
|
||||||
|
return promiseResult;
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
Loading…
x
Reference in New Issue
Block a user