Asincronía en métodos de clase
Parte de la sección Programación Orientada a Objetos del Journey de Dart de Coddy. Lección 80 de 110.
Ahora que sabes cómo gestionar la inicialización asíncrona con métodos de fábrica, veamos cómo hacer que los métodos de instancia normales sean asíncronos. Es sencillo: solo tienes que añadir async a cualquier método y hacer que devuelva un Future.
class WeatherService {
String _location;
WeatherService(this._location);
Future<String> fetchTemperature() async {
await Future.delayed(Duration(seconds: 1));
return '22°C in $_location';
}
Future<void> updateLocation(String newLocation) async {
await Future.delayed(Duration(milliseconds: 500));
_location = newLocation;
print('Location updated to $_location');
}
}
Future<void> main() async {
var service = WeatherService('London');
var temp = await service.fetchTemperature();
print(temp);
await service.updateLocation('Paris');
}Los métodos asíncronos pueden acceder a las variables de instancia y modificarlas, igual que los métodos normales. La diferencia clave es que quienes los llaman deben usar await para esperar el resultado. Los métodos que devuelven Future<void> no devuelven ningún valor, pero aun así hay que esperarlos si quieres asegurarte de que terminen antes de continuar.
También puedes combinar varias llamadas asíncronas dentro de un método o llamar a otros métodos asíncronos de la misma clase:
Future<String> getFullReport() async {
var temp = await fetchTemperature();
var humidity = await fetchHumidity();
return '$temp, Humidity: $humidity';
}Este patrón es esencial para las clases que interactúan con recursos externos —API, bases de datos o cualquier operación que lleve tiempo.
Desafío
Fácil¡Vamos a crear un gestor de cartera de acciones que administra los precios de las acciones y calcula el valor de la cartera mediante métodos asíncronos! Crearás una clase que simula la obtención de datos bursátiles en tiempo real y combina varias operaciones asíncronas para generar informes.
Organizarás tu código en dos archivos:
portfolio.dart: Crea una claseStockPortfolioque realiza un seguimiento de las acciones y sus cantidades. Tu clase debe tener:- Un
Map<String, int>privado llamado_holdingsque almacena los símbolos de las acciones y el número de acciones que se poseen - Un constructor que inicializa
_holdingscomo un mapa vacío - Un método
addStock(String symbol, int quantity)que añade o actualiza una posición en acciones (no es asíncrono) - Un método asíncrono
fetchPrice(String symbol)que devuelve unFuture<double>. Simula una demora de 50 milisegundos y después devuelve un precio calculado así: la longitud del símbolo multiplicada por 25.5 - Un método asíncrono
getStockValue(String symbol)que devuelve unFuture<double>. Debe esperar afetchPricepara el símbolo, multiplicar el resultado por la cantidad que se posee y devolver el valor total. Si el símbolo no está en las posiciones, devuelve 0.0 - Un método asíncrono
getTotalValue()que devuelve unFuture<double>. Debe calcular el valor combinado de todas las posiciones esperando agetStockValuepara cada acción y sumando los resultados - Un método asíncrono
generateReport()que devuelve unFuture<String>. Debe generar un informe que muestre el valor de cada acción y el total. Da formato a cada línea como[symbol]: $[value](valor con 1 decimal), seguida de una línea finalTotal: $[totalValue](también con 1 decimal)
- Un
main.dart: Importa el archivo de la cartera y demuestra cómo funcionan juntos los métodos asíncronos dentro de una clase:- Crea una instancia de
StockPortfolio - Añade estas posiciones:
AAPLcon 10 acciones,GOOGLcon 5 acciones,MSFTcon 8 acciones - Imprime
Fetching portfolio data... - Espera el resultado de
generateReport()e imprímelo
- Crea una instancia de
Observa cómo generateReport() llama a otros métodos asíncronos dentro de la misma clase y cómo cada método se basa en los demás. ¡Usa toStringAsFixed(1) para dar formato a los valores decimales!
Salida esperada:
Fetching portfolio data...
AAPL: $1020.0
GOOGL: $637.5
MSFT: $816.0
Total: $2473.5Pruébalo tú mismo
import 'portfolio.dart';
void main() async {
// TODO: Crea una instancia de StockPortfolio
// TODO: Añade las posiciones:
// - AAPL con 10 acciones
// - GOOGL con 5 acciones
// - MSFT con 8 acciones
// TODO: Imprime "Fetching portfolio data..."
// TODO: Espera e imprime el resultado de generateReport()
}
Esta lección incluye un breve cuestionario. Empieza la lección para responderlo y registrar tu progreso.
Todas las lecciones de Programación Orientada a Objetos
1Fundamentos de POO
Archivos externosLibrerías e importacionesIntroducción a la POOClases vs. ObjetosLa palabra clave thisMétodosVariables de instanciaConceptos básicos de constructoresResumen - Calculadora sencilla4Seguridad de nulos
Introducción a la seguridad de nulosNulables vs No nulablesLos operadores ? y !Palabra clave Late y Null SafetyOperadores Null-awareNull Safety en clasesResumen - Sistema de perfil de usuario7Clases abstractas e interfaces
Clases abstractasMétodos abstractosInterfaces en DartInterfaces implícitasImplementar vs. ExtenderInterfaces múltiplesRepaso - Calculadora de figuras10Colecciones y Genéricos
Visión general de List, Set y MapColecciones con seguridad de tiposClases genéricasMétodos genéricosRestricciones genéricasIterable e IteratorResumen - Almacenamiento genérico2Constructores en Dart
Constructor por defectoConstructores nombradosListas de inicializaciónConstructores constantesConstructores de fábricaConstructores de redireccionamientoResumen - Constructor de formas5Encapsulamiento
Miembros públicos vs. privadosLa convención del prefijo _Privacidad a nivel de libreríaProfundidad en Getters y SettersOcultamiento de informaciónResumen - Registros de estudiantes8Mixins
Introducción a los MixinsCreación de MixinsUso de múltiples MixinsPalabra clave on en MixinsMixin vs HerenciaMixin vs InterfazResumen - Sistema Animal11Métodos especiales
Sobrescritura de toString()Sobrescritura de hashCode y ==Interfaz ComparableMétodo call()Sobrescritura de noSuchMethodResumen - Colección personalizada14Patrones de diseño Parte 1
Introducción a los patrones de diseñoPatrón SingletonPatrón FactoryPatrón ObserverPatrón Strategy3Propiedades de clase
Miembros de instancia vs. estáticosCampos Final y ConstVariables LateMétodos y campos estáticosGetters y SettersResumen - Gestor de cuentas bancarias6Herencia
Herencia básicaLa palabra clave superSobrescritura de métodosLa anotación @overrideLa palabra clave final en clasesConstructores y herenciaResumen - Jerarquía de empleados9Polimorfismo
Fundamentos del polimorfismoPolimorfismo mediante interfacesComprobación de tipos en tiempo de ejecuciónLos operadores is y asPalabra clave covariantResumen - Procesador de pagos12POO Asíncrona
Futures y async/awaitFundamentos de StreamsStream ControllersConstructores asíncronosAsincronía en métodos de claseRepaso - Data Fetcher15Patrones de diseño Parte 2
Patrón CommandPatrón AdapterPatrón DecoratorPatrón Template MethodPatrón StatePatrón CompositePatrón RepositoryPractica por tu cuenta: Compilador de Dart online