I am using the official Telegram Api (TDLib) in Java to request information about all members of a group. Using their IDs I am sending asynchronous requests to the server and I receive User
objects for each request inside the ResultHandler like this:
private static ArrayList<TdApi.User> chatUsers= new ArrayList<>();
private static void addUsers(){
for (int i = 0; i < userIDs.length; i++){
client.send(new TdApi.GetUser(userIDs[i]), new Client.ResultHandler() {
@Override
public void onResult(TdApi.Object object) {
TdApi.User user = (TdApi.User)object;
chatUsers.add(user);
}
});
}
}
Since I am pretty new to anychronous requests in Java I am wondering the following:
What would be an appropriate approach to call this method and wait for all results received before moving on?
Generally, when calling several requests consecutively and waiting for each result before moving on with the next request, what is an usual approach instead of nesting the requests inside of each other to sync them in Java? I want to avoid something like this:
private static void getSupergroupId(int chatId){ //first step client.send(new TdApi.GetChat(chatId), new Client.ResultHandler() { @Override public void onResult(TdApi.Object object) { supergroupId = ((TdApi.ChatTypeSupergroup)((TdApi.Chat)object).type).supergroupId; //second step when result received client.send(new TdApi.GetSupergroupMembers(supergroupId, null, 0, 200), new Client.ResultHandler() { @Override public void onResult(TdApi.Object object) { chatMembers = ((TdApi.ChatMembers)object).members; //further steps which need to wait for the result of the step before } }); } }); }
Thank you!
1 One of Java Synchronizers should work. I would start with
CountDownLatch
as it the simplest one.Notice that
chatUsers
is accessed from different threads so access to it should be guarded by a lock. I usedCollections.synchronizedList
in the example for simplicity. However you should use more fine-grained approach.2 Take a look at
Completablefuture
, seems that is what you are looking for.Notice that the same trick with
CountDownLatch
is used to wait for the result. Again you result from callback should be guarded by lock as it is accessed by different threads. To be 100% clear it's not required because of piggybacking onCountDownLatch
however i would recommend to use explicit synchronization anyway, for exampleAtomicReference
.