It would be best if you had a way to wait for the status of any of the items to change.
For example, if you were dealing with processes, you could use.
my %children = map { $_ => 1 } @pids;
while (%children) {
my $pid = wait();
my $status = $?;
delete($children{$pid});
if ( $status & 0x7F ) { warn("Child $pid killed by signal ".( $status & 0x7F )."\n"); }
elsif ( $status >> 8 ) { warn("Child $pid exited with error ".( $status >> 8 )."\n"); }
else { print("Child $pid exited successfully\n"); }
}
Otherwise, you will need to poll.
use Time::HiRes qw( sleep ); # Time::HiRes::sleep supports fractional durations.
my %foos = map { $_ => 1 } @foo_ids;
while (%foos) {
for my $foo_id (keys(%foos)) {
if (checkStatus($foo_id, $server) eq 'Z') {
delete($foos{$foo_id});
# ...?
}
}
sleep(0.1); # To avoid using 100% CPU.
}
Note that in both cases, you can use the value of the hash elements to contain information about the thing.
# When creating the foos.
$foos{$foo_id} = $foo;
# When waiting the foos.
my $foo = delete($foos{$foo_id});