es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

Extender una Future y/o preservar la funcionalidad de await

Me gustaría extender la clase Future y darle más funcionalidad mientras mantengo la funcionalidad de la palabra clave await. Según entiendo, las Futures no se pueden extender directamente en Dart, ¿pero tal vez hay otra forma de lograr lo que quiero?

La clase que estoy tratando de crear es efectivamente un mecanismo para interactuar con una API. El servidor es similar a RPC en el sentido de que su API puede ser bidireccional mientras la solicitud esté abierta (los mensajes pueden ir y venir entre el servidor y el cliente hasta que se considere resuelta la solicitud).

Para hacer que la biblioteca del cliente sea más usable, estoy tratando de crear una clase Request que tenga todas las ventajas de un Future normal, pero también la capacidad de usar una función when() o on() que efectivamente escucha las actualizaciones durante la resolución del futuro.

Algunas partes de código de ejemplo de uso:

Request(args)
  .when('SomeEvent', (event) => print('Una actualización: $event'))
  .then((response) => print('La respuesta final: $response'))
  .onError((err) => print('Algún error: $err'));

// Esto también debe funcionar:

final response = await Request(args);

Hasta ahora, tengo algo como esto, pero la palabra clave await no funciona:

class Request {
  final Completer _completer = Completer();

  Request(args) {
    // Configurar y hacer alguna solicitud a una API y responder/actualizar usando response|error|update
  }

  Future<dynamic> then(fn) async {
    // ¿Debería esto realmente devolver una Request?
    return _completer.future.then(fn);
  }

  Future<dynamic> onError(fn) async {
    // ¿Debería esto realmente devolver una Request?
    return _completer.future.onError(fn);
  }

  Request when(String eventName, Function fn) {
    // Adjuntar un listener/stream que dispara fn en una actualización
    return this;
  }

  void _response(res) {
    _completer.complete(res);
  }

  void _error(err) {
    _completer.completeError(err);
  }

  void _update(upd) {
    // Se proporciona alguna actualización de la solicitud
  }
}

¿Es lo que estoy intentando imposible en Dart?

Tags:  , ,

Answer

  1. Avatar for davy.ai

    No es posible extender directamente la clase Future en Dart, pero puedes crear una nueva clase que envuelva un Future y añada la funcionalidad adicional que necesitas. En tu caso, puedes crear una clase Request que envuelva un Completer y un Future, y añada los métodos when() y on():

    class Request {
      final Completer _completer = Completer();
      final Future _future;
    
      Request(args) {
        // realizar una solicitud a una API y responder/actualizar usando _response()|_error()|_update()
        // configurar _future para completar cuando _completer se complete
        _future = _completer.future;
      }
    
      Future<dynamic> then(Function fn) {
        return _future.then(fn);
      }
    
      Future<dynamic> catchError(Function fn) {
        return _future.catchError(fn);
      }
    
      Request when(String eventName, Function fn) {
        // adjuntar un listener/flujo que dispare fn al actualizarse
        return this;
      }
    
      void _response(res) {
        _completer.complete(res);
      }
    
      void _error(err) {
        _completer.completeError(err);
      }
    
      void _update(upd) {
        // Se proporciona alguna actualización de la solicitud
      }
    }
    

    Para poder usar await con tu clase Request, necesitas asegurarte de que tu clase implementa la interfaz Future. Para hacer esto, simplemente añade los métodos necesarios a tu clase Request:

    class Request implements Future {
      // ...
    }
    

    Con esta configuración, ahora puedes usar await con instancias de Request:

    dart
    final response = await Request(args);

Comments are closed.