Skip to content

Commit 137012b

Browse files
committed
feat: use multiGet in connect calls
1 parent cc0d468 commit 137012b

File tree

1 file changed

+33
-22
lines changed

1 file changed

+33
-22
lines changed

lib/Onyx.js

Lines changed: 33 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -372,6 +372,24 @@ function sendDataToConnection(config, val, key) {
372372
}
373373
}
374374

375+
/**
376+
* Retrieve all the connections that should be made for a given mapping
377+
* @param {object} mapping
378+
* @param {string} mapping.key
379+
*
380+
* @returns {Promise<string[]>}
381+
*/
382+
function getKeysToConnectTo(mapping) {
383+
if (isCollectionKey(mapping.key)) {
384+
// Find all collection items keys matching this mapping
385+
return getAllKeys()
386+
.then(keys => _.filter(keys, key => isKeyMatch(mapping.key, key)));
387+
}
388+
389+
// Otherwise it's just a single item, wrap it in a list
390+
return Promise.resolve([mapping.key]);
391+
}
392+
375393
/**
376394
* Subscribes a react component's state directly to a store key
377395
*
@@ -407,34 +425,27 @@ function connect(mapping) {
407425
addLastAccessedKey(mapping.key);
408426
}
409427
})
410-
.then(getAllKeys)
411-
.then((keys) => {
412-
// Find all the keys matched by the config key
413-
const matchingKeys = _.filter(keys, key => isKeyMatch(mapping.key, key));
414-
415-
// If the key being connected to does not exist, initialize the value with null
428+
.then(() => getKeysToConnectTo(mapping))
429+
.then((matchingKeys) => {
430+
// When there are no matching keys, initialize the value with null
416431
if (matchingKeys.length === 0) {
417432
sendDataToConnection(mapping, null);
418-
return;
433+
return [];
419434
}
420435

421-
// When using a callback subscriber we will trigger the callback
422-
// for each key we find. It's up to the subscriber to know whether
423-
// to expect a single key or multiple keys in the case of a collection.
424-
// React components are an exception since we'll want to send their
425-
// initial data as a single object when using collection keys.
436+
return multiGet(matchingKeys);
437+
})
438+
.then((result) => {
439+
/* For React components subscribed to collections we want to send the data
440+
* as a single object and trigger setState just once */
426441
if (mapping.withOnyxInstance && isCollectionKey(mapping.key)) {
427-
Promise.all(_.map(matchingKeys, key => get(key)))
428-
.then(values => _.reduce(values, (finalObject, value, i) => ({
429-
...finalObject,
430-
[matchingKeys[i]]: value,
431-
}), {}))
432-
.then(val => sendDataToConnection(mapping, val));
433-
} else {
434-
_.each(matchingKeys, (key) => {
435-
get(key).then(val => sendDataToConnection(mapping, val, key));
436-
});
442+
return sendDataToConnection(mapping, result);
437443
}
444+
445+
/* When using a callback subscriber we will trigger the callback
446+
* for each key we find. It's up to the subscriber to know whether
447+
* to expect a single key or multiple keys in the case of a collection. */
448+
_.each(result, (val, key) => sendDataToConnection(mapping, val, key));
438449
});
439450

440451
return connectionID;

0 commit comments

Comments
 (0)