这是indexloc提供的服务,不要输入任何密码
Skip to content
This repository was archived by the owner on Sep 2, 2020. It is now read-only.
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
68 changes: 52 additions & 16 deletions bolts-tasks/src/main/java/bolts/Task.java
Original file line number Diff line number Diff line change
Expand Up @@ -603,26 +603,62 @@ public Task<Void> continueWhile(final Callable<Boolean> predicate,
* Continues a task with the equivalent of a Task-based while loop, where the body of the loop is
* a task continuation.
*/
public Task<Void> continueWhile(final Callable<Boolean> predicate,
final Continuation<Void, Task<Void>> continuation, final Executor executor,
public Task<Void> continueWhile(
final Callable<Boolean> predicate,
final Continuation<Void, Task<Void>> continuation,
final Executor executor,
final CancellationToken ct) {
final Capture<Continuation<Void, Task<Void>>> predicateContinuation =
new Capture<>();
predicateContinuation.set(new Continuation<Void, Task<Void>>() {
return this.onSuccessTask(new Continuation<TResult, Task<Void>>() {
@Override
public Task<Void> then(Task<Void> task) throws Exception {
if (ct != null && ct.isCancellationRequested()) {
return Task.cancelled();
}
public Task<Void> then(Task<TResult> task) throws Exception {
final bolts.TaskCompletionSource<Void> tcs = new bolts.TaskCompletionSource<>();

if (predicate.call()) {
return Task.<Void> forResult(null).onSuccessTask(continuation, executor)
.onSuccessTask(predicateContinuation.get(), executor);
}
return Task.forResult(null);
final Continuation<Void, Void> next = new Continuation<Void, Void>() {
@Override
public Void then(Task<Void> task) throws Exception {
try {
if (task.isFaulted()) {
tcs.setError(task.getError());
return null;
}
if (task.isCancelled()) {
tcs.setCancelled();
return null;
}
if (ct != null && ct.isCancellationRequested()) {
tcs.setCancelled();
return null;
}

try {
if (!predicate.call()) {
tcs.setResult(null);
return null;
}
final Task<Void> result = continuation.then(task);
// Note: for compatability we allow null to continue instead of ending the loop.
// if (result == null) {
// tcs.setResult(null);
// return null;
// }
(result != null ? result : Task.<Void>forResult(null)).continueWith(this, executor);
} catch (CancellationException e) {
tcs.setCancelled();
} catch (Exception e) {
tcs.setError(e);
}
} catch(Exception e) {
tcs.setError(new ExecutorException(e));
}
return null;
}
};

next.then(Task.forResult(null));

return tcs.getTask();
}
});
return makeVoid().continueWithTask(predicateContinuation.get(), executor);
}, executor, ct);
}

/**
Expand Down
76 changes: 76 additions & 0 deletions bolts-tasks/src/test/java/bolts/TaskTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -1007,6 +1007,82 @@ public Void then(Task<Void> task) throws Exception {
});
}

@Test
public void testContinueWhileTask() {
final AtomicInteger count = new AtomicInteger(0);
runTaskTest(new Callable<Task<?>>() {
public Task<?> call() throws Exception {
return Task.forResult(null).continueWhile(new Callable<Boolean>() {
public Boolean call() throws Exception {
return count.get() < 10;
}
}, new Continuation<Void, Task<Void>>() {
public Task<Void> then(Task<Void> task) throws Exception {
count.incrementAndGet();
return Task.<Void>forResult(null);
}
}).continueWith(new Continuation<Void, Void>() {
public Void then(Task<Void> task) throws Exception {
assertEquals(10, count.get());
return null;
}
});
}
});
}

@Test
public void testContinueWhileTaskCancelledParent() {
final AtomicInteger count = new AtomicInteger(0);
runTaskTest(new Callable<Task<?>>() {
public Task<?> call() throws Exception {
return Task.cancelled().continueWhile(new Callable<Boolean>() {
public Boolean call() throws Exception {
return count.get() < 10;
}
}, new Continuation<Void, Task<Void>>() {
public Task<Void> then(Task<Void> task) throws Exception {
count.incrementAndGet();
return Task.<Void>forResult(null);
}
}).continueWith(new Continuation<Void, Void>() {
public Void then(Task<Void> task) throws Exception {
assertEquals(0, count.get());
assertTrue(task.isCancelled());
return null;
}
});
}
});
}

@Test
public void testContinueWhileTaskFailedParent() {
final AtomicInteger count = new AtomicInteger(0);
final Exception exception = new Exception();
runTaskTest(new Callable<Task<?>>() {
public Task<?> call() throws Exception {
return Task.forError(exception).continueWhile(new Callable<Boolean>() {
public Boolean call() throws Exception {
return count.get() < 10;
}
}, new Continuation<Void, Task<Void>>() {
public Task<Void> then(Task<Void> task) throws Exception {
count.incrementAndGet();
return Task.<Void>forResult(null);
}
}).continueWith(new Continuation<Void, Void>() {
public Void then(Task<Void> task) throws Exception {
assertEquals(0, count.get());
assertEquals(exception, task.getError());
return null;
}
});
}
});
}


@Test
public void testContinueWhileAsync() {
final AtomicInteger count = new AtomicInteger(0);
Expand Down