Even though there's multiple similar questions here on StackOverflow, I haven't been able to solve this, please bear with me:
In an Angular 16 application I have a functionality to batch rename hundreds of users. Thus, I have an array of RenameUser
objects, each one having an async method .executeRename()
performing an API call to rename a user. To not overwhelm the API, these should be triggered with a 200ms delay between them. Once all users have been renamed, I would like to run other tasks.
Summarized: Trigger a bunch of async operations with a 200ms delay between them, do something when all are complete.
I have managed to delay the calls, and I do not care how long a single call takes to finish, but I need to know when all tasks have finished.
This is the solution I came up with, I would run the triggerRenameProcess()
method to start the process.
async triggerRenameProcess(users: RenameUser[]) {
try {
await this.renameUsersWithDelay(users, 200);
console.log('All users renamed');
} catch (error) {
console.error('Exception while renaming users: ', error);
}
}
renameUsersWithDelay(users: RenameUser[], delay: number): Promise<void> {
return new Promise<void>((resolve) => {
let currentIndex = 0;
const executeNext = () => {
if (currentIndex < users.length) {
const user = users[currentIndex];
user.executeRename().then(() => {
currentIndex++;
setTimeout(executeNext, delay);
});
} else {
resolve();
}
};
});
}
I kind of understand what the problem is, the renameUsersWithDelay()
returns a Promise that can be awaited, but that will happen once all requests have been triggered - it is not waiting for the longest running one to complete. I can make it wait for every single one and run them sequentially, but that's not what it is supposed to do...
I did some research and found this question or this one, but they seem not to address the same issue - and frankly, I am not too familiar with JavaScript - I feel more at home in .NET where I just would use something like .WaitAll() (and probably use a more sophisticated throttling pattern), but I'm not sure how to achieve the same thing in TypeScript.