Да, reset
s может быть вложенным, и, да, это может быть полезно.В качестве примера я недавно создал прототип API для проекта scalagwt , который позволил бы разработчикам GWT писать асинхронные RPC (вызовы удаленных процедур) в прямом стиле (в отличие от стиля передачи обратных вызовов, который используется вGWT для Java).Например:
field1 = "starting up..." // 1
field2 = "starting up..." // 2
async { // (reset)
val x = service.someAsyncMethod() // 3 (shift)
field1 = x // 5
async { // (reset)
val y = service.anotherAsyncMethod() // 6 (shift)
field2 = y // 8
}
field2 = "waiting..." // 7
}
field1 = "waiting..." // 4
В комментариях указывается порядок исполнения.Здесь метод async
выполняет reset
, а каждый вызов службы выполняет shift
(вы можете увидеть реализацию на моем github fork , в частности Async.scala ).
Обратите внимание, как вложенная async
меняет поток управления.Без этого строка field2 = "waiting"
не будет выполняться до тех пор, пока не будет успешно завершено выполнение второго RPC.
Когда выполняется RPC, реализация захватывает продолжение до самого внутреннего async
границы и приостанавливает ее выполнение после успешного завершения RPC.Таким образом, вложенный блок async
позволяет элементу управления сразу переходить на линию после него, как только будет выполнен второй RPC.С другой стороны, без этого вложенного блока продолжение будет продолжаться до конца внешнего async
блока, и в этом случае весь код во внешнем async
будет блокироваться на каждом RPC.