API задачи служб Google Play: continueWith vs continueWithTask
Это задание.
в чем разница между task.continueWith()
и task.continueWithTask()
, вы можете привести пример для каждого из них?
3 ответов
основная разница между continueWith и continueWithTask является одним из общих типов продолжение вы переходите к нему.
вы можете думать о продолжении как о чем-то, что преобразует некоторый тип ввода в некоторый тип вывода. Если вы определяете Continuation<IN, OUT>
, где IN
- Это тип ввода, переданный его then
способ через Task<IN>
и OUT
- это тип, который возвращает метод.
при вызове continueWith
, передать Continuation<IN, OUT>
и then
ожидается, что метод вычислит и вернет OUT
значение дано Task<IN>
значение в качестве входных данных. Вы можете сделать это, если у вас нет никакой блокирующей работы для преобразования, такой как уменьшение целого массива до суммы его элементов или подсчет количества слов в строке.
при вызове continueWithTask
, передать Continuation<IN, Task<OUT>>
и then
ожидается, что метод вернет Task<OUT>
что в конечном итоге создает OUT
значение, учитывая IN
значение в качестве входных данных. Вы можете выбрать это, если сможете делегировать работу преобразования существующей многоразовой задаче.
практически говоря, вы не обязаны выбирать тот или иной для выполнения своей работы. Это вопрос стиля, или если у вас есть хороший Task
готов делегировать свой разговор, а не Continuation
. Обычно вы используете продолжения, только если у вас есть конвейер преобразований в цепочку вместе.
ссылки javadoc здесь показывают некоторые примеры продолжений. Также, чтобы узнать больше, вы можете прочитать о них в часть третья из моей серии блогов. Справедливости ради,continueWithTask
- единственная часть API задач, которую я непосредственно не обсуждаю нигде в этой серии, в основном потому, что концептуально она не сильно отличается от continueWith
.
чтобы добавить к тому, что сказал Дуг, я бы сказал так:
continueWith
обернет результат then
метод Task
. continueWithTask
не будет; он ожидает then
метод, чтобы возвратить Task
, и таким образом избегает двойной упаковки задачи внутри задачи.
continueWithTask
идеально подходит, когда вы хотите использовать продолжение и TaskCompletionSource вместе.
я хотел бы добавить, что continueWith
и continueWithTask
действительно попал в беду, очевидно, потому, что я действительно не понимал API, но также и имя запутало меня. Может быть, пример моей неудачи может помешать другим сделать то же самое.
tl; dr
когда использовать какой метод:
использовать
continueWith
Если вы хотите использовать результат предыдущей задачи и вернуть новый результат в пределах вашего продолженияthen
метод. И нужно передать его какому-нибудь другому продолжению или использовать потом в слушателях. возвращаемое значение continueWith-это задача, которая просто обертывает ваше возвращаемое значениеthen
метод.использовать
continueWithTask
если вы хотите использовать результат предыдущей задачи, и несколько использовать его в новая задача, что вы создаете в рамках вашего продолженияthen
метод. возвращаемое значение continueWithTask-это задача, которую вы создаете внутриthen
и имеет собственный общий результат.
Do не верните задачу в своем продолжении и используйте ее с 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);
);
};
}
что случилось? The onCompleteListener
был вызван напрямую, потому что мой then
метод был выполнен и вернул его результат, который был экземпляром AdditionalTask
.
Это обвели в другое задание и передал для onCompleteListener в результате.
и мой AdditionalTask никогда не выполняется.
вот почему вы должны использовать continueWithTask, если вы возвращаете задачу, в то время.