diff --git a/IntegrationTests/AsyncStorageTest.js b/IntegrationTests/AsyncStorageTest.js index 3bd313a7fd0e96..06ea818e4511a4 100644 --- a/IntegrationTests/AsyncStorageTest.js +++ b/IntegrationTests/AsyncStorageTest.js @@ -142,12 +142,30 @@ function testMerge() { expectAsyncNoError('testMerge/setItem', err3); expectEqual(JSON.parse(result), VAL_MERGE_EXPECT, 'testMerge'); updateMessage('objects deeply merged\nDone!'); + runTestCase('multi set and get', testOptimizedMultiGet); + }); + }); + }); +} + +function testOptimizedMultiGet() { + let batch = [[KEY_1, VAL_1], [KEY_2, VAL_2]]; + let keys = batch.map(([key, value]) => key); + AsyncStorage.multiSet(batch, (err1) => { + // yes, twice on purpose + ;[1, 2].forEach((i) => { + expectAsyncNoError(`${i} testOptimizedMultiGet/multiSet`, err1); + AsyncStorage.multiGet(keys, (err2, result) => { + expectAsyncNoError(`${i} testOptimizedMultiGet/multiGet`, err2); + expectEqual(result, batch, `${i} testOptimizedMultiGet multiGet`); + updateMessage('multiGet([key_1, key_2]) correctly returned ' + JSON.stringify(result)); done(); }); }); }); } + var AsyncStorageTest = React.createClass({ getInitialState() { return { diff --git a/Libraries/Storage/AsyncStorage.js b/Libraries/Storage/AsyncStorage.js index eb41c8a736f560..f1ed35c3c1c5f4 100644 --- a/Libraries/Storage/AsyncStorage.js +++ b/Libraries/Storage/AsyncStorage.js @@ -180,14 +180,16 @@ var AsyncStorage = { // 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. + // + // Is there a way to avoid using the map but fix the bug in this breaking test? + // https://github.com/facebook/react-native/commit/8dd8ad76579d7feef34c014d387bf02065692264 + let map = {}; + result.forEach(([key, value]) => map[key] = value); 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; - }); - + let requestResult = requestKeys.map(key => [key, map[key]]); request.callback && request.callback(null, requestResult); request.resolve && request.resolve(requestResult); } @@ -214,6 +216,7 @@ var AsyncStorage = { var getRequest = { keys: keys, callback: callback, + // do we need this? keyIndex: this._getKeys.length, resolve: null, reject: null, @@ -225,7 +228,12 @@ var AsyncStorage = { }); this._getRequests.push(getRequest); - this._getKeys.push.apply(this._getKeys, keys); + // avoid fetching duplicates + keys.forEach(key => { + if (this._getKeys.indexOf(key) === -1) { + this._getKeys.push(key); + } + }); return promiseResult; },