Function X:
Create 1000 objects
Function Y:
If object count is less than 1000. -Wait 1 second. -Call Function Y
Else Destroy all objects
By calling Function Y inside of Function Y it gives you a loop that you can easily control. You have to be careful though that you don't create an endless loop. You can check this by adding a global variable and each time Function Y runs it can add 1 to the variable. This allows you to check in debugger how many times Function Y runs. When you confirm Function Y is acting how it should then delete the global variable. dop2000's would be more efficient though, but I think it has to do with how the logic is set up. I never messed with asynchronous yet.
***edit***
The wait in Function Y was just to reduce how many times Function Y is called while waiting for Function X to complete. It isn't needed unless you just want a very small performance increase.