这大约是Task。
task.continueWith()
和task.continueWithTask()
之间有什么区别,你能为每个人提供一个例子吗?
答案 0 :(得分:11)
The primary difference between continueWith and continueWithTask is one of the generic types of the Continuation you pass to it.
You can think of a Continuation as something that converts some input type to some output type. If you define a Continuation<IN, OUT>
, where IN
is the input type passed to its then
method via a Task<IN>
, and OUT
is the type that method returns.
When calling continueWith
, you pass a Continuation<IN, OUT>
, and the then
method is expected to compute and return the OUT
value given a Task<IN>
value as input. You might choose to do this if you don't have any blocking work to do for the conversion, such as reducing an integer array to the sum of its elements or counting the number of words in a String.
When calling continueWithTask
, you pass a Continuation<IN, Task<OUT>>
, and the then
method is expected to return a Task<OUT>
that eventually generates the OUT
value, given the IN
value as input. You might choose this if you are able to delegate the conversion work to an existing reusable Task.
Practically speaking, you aren't required to choose one or the other to do your work. It's a matter of preferred style, or if you have a nice Task
ready to delegate your conversation rather than a Continuation
. Typically you only use a Continuations if you have a pipeline of conversions to chain together.
The javadoc links here show some examples of Continuations. Also, to learn more, you can read about them in part three of my blog series. To be fair, continueWithTask
is the only part of the Task API I don't directly discuss anywhere in that series, mostly because conceptually it doesn't differ very much from continueWith
.
答案 1 :(得分:6)
只是为了补充道格说的话,我会这样说:
continueWith
会将then
方法的结果包装在Task
中。 continueWithTask
不会;它期望then
方法返回Task
,从而避免在任务中双重包装任务。
continueWithTask
是完美的。
答案 2 :(得分:3)
我想补充一点,continueWith
和continueWithTask
确实让我陷入困境,显然是因为我没有真正理解API,但命名也让我感到困惑。也许我失败的一个例子可以阻止其他人做同样的事情。
何时使用哪种方法:
如果您想使用上一个任务的结果并在Continuation的continueWith
方法中返回新结果,请使用then
。而且你需要把它交给其他一些延续,或者之后在听众中使用它。 continueWith的返回值是一个只包含then
方法返回值的任务。
如果要使用上一个任务的结果,请使用continueWithTask
,
并在您的Continuation的then
方法中创建的新任务中使用它。 continueWithTask的返回值是您在then
内创建的任务,并且具有自己的通用结果。
NOT 在你的continuation中返回一个任务然后和continueWith一起使用它。它可能会在没有警告的情况下编译和执行多年,但也没有完成任务。
如果你在
continueWith
之后直接追加一个监听器,那么这个监听器 将给你一项任务,只包含你then
返回的结果 值。如果此返回值本身就是一个任务,那么不要指望它 执行(!!!)。
长篇故事!
我有一个这样的调用链:
private Task<SomeResult> getTask() {
PreloadingTask.create().continueWith(additionalTask()).addOnCompleteListener(task -> {
if (task.isSuccessful()) {
source.setResult(someResult);
} else {
source.setException(new Exception());
}
});
return source.getTask();
}
正如您所看到的,additionalTask()
必须返回某种Continuation<IN, OUT>
,然后将该方法实现为
@Override
public OUT then(Task<IN> task){ ... }};
在我的情况下,我不需要检查OUT
,因为我只是想在PreloadingTask
完成后进行一些额外的计算,并将结果转发到我的additionalTask()
继续。
我想从additionalTask()
执行任务,然后应该调用onCompleteListener
。
private Continuation<PreviousResult, Task<Void>> additionalTask() {
return task -> {
PreviousResult r = task.getResult();
simpleResultModification(r);
return new AdditionalTask(r);
);
};
}
发生什么事了?直接调用了onCompleteListener
,因为我的then
方法已执行并返回了它的结果,这是AdditionalTask
的一个实例。
然后,AdditionalTask
将包装成另一个任务,并将onCompleteListener作为结果移交。
我的 AdditionalTask 从未执行过。
这就是为什么你应该在返回任务时使用continueWithTask。
答案 3 :(得分:0)
continueWith()
和continueWithTask()
之间与任务取消有很大的区别。
更多信息在这里-Task API docs。
continueWith()
:如果取消了上一个任务,则返回的任务也将被取消,并且继续执行将不会执行。
continueWithTask()
:如果取消了先前的任务,则继续执行 ,并且task.isCanceled()为true可以在继续中看到。