Skip to content

Instantly share code, notes, and snippets.

@ankitmundada
Last active March 13, 2021 09:30
Show Gist options
  • Save ankitmundada/a5346e93842524bd687a6529b329cd39 to your computer and use it in GitHub Desktop.
Save ankitmundada/a5346e93842524bd687a6529b329cd39 to your computer and use it in GitHub Desktop.
import 'dart:async';
///
/// Simulating DB
///
Map<String, String> data = {
'id1': 'data for id1',
'id2': 'data for id2',
'id3': 'data for id3',
'id4': 'data for id4',
'id5': 'data for id5',
};
///
/// Simulating API Call
///
Future<Map<String, String>> getDataById(List<String> ids) async {
Map<String, String> result = {};
for (final entry in data.entries) {
if (ids.contains(entry.key)) result.addEntries([entry]);
}
// simulating network delay
await Future.delayed(const Duration(seconds: 1));
return result;
}
///
/// api Batcher: Functional
///
typedef Future<String> MakeApiCall(String id);
final List<String> requestedIds = [];
Completer? apiBatcherCompleter;
MakeApiCall apiBatcher(Duration batchDelay) {
return (id) async {
if (apiBatcherCompleter == null || apiBatcherCompleter!.isCompleted) {
requestedIds.clear();
apiBatcherCompleter = Completer();
apiBatcherCompleter!.complete(Future.delayed(batchDelay)
.then((value) => getDataById(requestedIds)));
}
requestedIds.add(id);
final resp = await apiBatcherCompleter!.future;
return Future.value(resp[id]);
};
}
MakeApiCall makeApiCall = apiBatcher(const Duration(seconds: 1));
/// Run using `dart ./batcher.dart`
main(List<String> args) {
// first batch
Future.delayed(const Duration(milliseconds: 200)).then((value) {
makeApiCall('id1').then((value) {
print("\nfirst batch");
print(value);
});
});
Future.delayed(const Duration(milliseconds: 600)).then((value) {
makeApiCall('id1').then((value) {
print(value);
});
});
Future.delayed(const Duration(milliseconds: 1100)).then((value) {
makeApiCall('id1').then((value) {
print(value);
});
});
// second batch
Future.delayed(const Duration(milliseconds: 1300)).then((value) {
makeApiCall('id2').then((value) {
print("\n\nsecond batch");
print(value);
});
});
Future.delayed(const Duration(milliseconds: 1600)).then((value) {
makeApiCall('id2').then((value) {
print(value);
});
});
}
@ankitmundada
Copy link
Author

ankitmundada commented Mar 13, 2021

Run using dart ./batcher.dart

Expected output:

first batch
data for id1
data for id1
data for id1


second batch
data for id2
data for id2

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment