2011-06-08 13 views

Respuesta

6

Sí, reset s se pueden anidar, y, sí, puede ser útil. Como ejemplo, recientemente prototipé una API para el scalagwt project que permitiría a los desarrolladores de GWT escribir RPC asíncronas (llamadas a procedimientos remotos) en un estilo directo (a diferencia del estilo de retrollamada que se utiliza en GWT para Java). Por ejemplo:

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 

Los comentarios indican el orden de ejecución. Aquí, el método async realiza un reset, y cada llamada de servicio realiza un shift (puede ver la implementación en my github fork, específicamente Async.scala).

Observe cómo el async anidado cambia el flujo de control. Sin él, la línea field2 = "waiting" no se ejecutará hasta después de la finalización exitosa del segundo RPC.

Cuando se realiza una llamada RPC, la aplicación captura la continuación hasta el más interior async límite, y suspende para su ejecución al término de la RPC. Por lo tanto, el bloque anidado async permite que el control fluya inmediatamente a la línea tan pronto como se realice el segundo RPC. Sin ese bloque anidado, por otro lado, la continuación se extendería hasta el final del bloque externo async, en cuyo caso todo el código dentro de async externo bloquearía en todos y cada uno de los RPC.

1

reset forma una abstracción para que el código externo no se vea afectado por el hecho de que el código interno se implementa con la magia de continuación. Entonces, si está escribiendo código con reinicio y desplazamiento, puede llamar a otro código que puede o no implementarse con reinicio y cambio también. En este sentido, se pueden anidar.

Cuestiones relacionadas