jdeferred/jdeferred — pull request #19 by tburch (2014-01-14 17:20:29+00:00)
Title: Support for whenAny

[Pull request for issue #17](https://github.com/jdeferred/jdeferred/issues/17)

Would it be possible to support a whenAny method where you can have several Callables that as soon as one is successfully returned, the DoneCallback with the result is called with the result (and canceling/failing all remaining Callables if they can be canceled)?

Here's a unit test for the use case:
```
@Test(timeout = 3000)
public void testWhenAny() {
final AtomicInteger doneCount = new AtomicInteger();
final AtomicInteger failCount = new AtomicInteger();
final AtomicBoolean callable1Run = new AtomicBoolean(false);
final AtomicBoolean callable2Run = new AtomicBoolean(false);
final AtomicBoolean callable3Run = new AtomicBoolean(false);

Promise p = deferredManager.whenAny(new Callable() {
public Integer call() {
try {
Thread.sleep(2000);
callable1Run.set(true);
} catch (InterruptedException e) {
}

return 100;
}
}, new Callable() {
public Integer call() {
try {
Thread.sleep(500);
callable2Run.set(true);
} catch (InterruptedException e) {
}

throw new RuntimeException("Oops");
}
}, new Callable() {
public String call() {
try {
Thread.sleep(5000);
callable3Run.set(true);
} catch (InterruptedException e) {
}

return "Hello";
}
}).then(new DoneCallback() {
public void onDone(OneResult result) {
Assert.assertEquals(100, result.getResult());
doneCount.incrementAndGet();
}
}).fail(new FailCallback() {
public void onFail(OneReject result) {
if (failCount.incrementAndGet() == 1) {
Assert.assertEquals(RuntimeException.class, result.getReject().getClass());
RuntimeException e = (RuntimeException) result.getReject();
Assert.assertEquals("Oops", e.getMessage());
}
}
});

Assert.assertTrue(callable1Run.get());
Assert.assertTrue(callable2Run.get());
Assert.assertFalse(callable3Run.get());
Assert.assertEquals(1, doneCount.get());
Assert.assertEquals(2, failCount.get());
}
```