Saltar al contenido

Dart, ¿cómo crear un futuro para volver en tus propias funciones?

Deseamos mostrarte la mejor respuesta que hemos encontrado en línea. Esperamos que te sea útil y si quieres compartir cualquier detalle que nos pueda ayudar a mejorar hazlo libremente.

Si necesita crear un futuro, puede utilizar un Completer. Ver Completer clase en los documentos. Aquí hay un ejemplo:

Future> GetItemList()
  var completer = new Completer>();

  // At some time you need to complete the future:
  completer.complete(new List());

  return completer.future;

Pero la mayoría de las veces no es necesario crear un futuro con un complemento. Como en este caso:

Future> GetItemList()
  var completer = new Completer();

  aFuture.then((a) 
    // At some time you need to complete the future:
    completer.complete(a);
  );

  return completer.future;

El código puede volverse muy complicado si se utilizan complementos. Simplemente puede usar lo siguiente en su lugar, porque then() devuelve un Future, también:

Future> GetItemList()
  return aFuture.then((a) 
    // Do something..
  );

O un ejemplo para el archivo io:

Future> readCommaSeperatedList(file)
  return file.readAsString().then((text) => text.split(','));

Consulte esta publicación de blog para obtener más sugerencias.

Simplemente puede usar el Futurevalue constructor de la fábrica:

return Future.value('Back to the future!');

Devolviendo un futuro desde tu propia función

Esta respuesta es un resumen de las muchas formas en que puede hacerlo.

Punto de partida

Su método podría ser cualquier cosa, pero por el bien de estos ejemplos, digamos que su método es el siguiente:

int cubed(int a) 
  return a * a * a;

Actualmente puedes usar tu método así:

int myCubedInt = cubed(3);  // 27

Sin embargo, desea que su método devuelva un Future como esto:

Future myFutureCubedInt = cubed(3);

O para poder usarlo de manera más práctica así:

int myCubedInt = await cubed(3);

Todas las siguientes soluciones muestran formas de hacerlo.

Solución 1: constructor Future ()

La solución más básica es utilizar el constructor generativo de Future.

Future cubed(int a) 
  return Future(() => a * a * a);

Cambié el tipo de retorno del método a Future y luego pasó el trabajo de la vieja función como una función anónima a la Future constructor.

Solución 2: constructor con nombre futuro

Los futuros pueden completarse con un valor o un error. Por lo tanto, si desea especificar alguna de estas opciones explícitamente, puede utilizar la Future.value o Future.error constructores con nombre.

Future cubed(int a) 
  if (a < 0) 
    return Future.error(ArgumentError("'a' must be positive."));
  
  return Future.value(a * a * a);

No permitir un valor negativo para a es un ejemplo elaborado para mostrar el uso de la Future.error constructor. Si no hay nada que produzca un error, simplemente puede usar el Future.value constructor así:

Future cubed(int a) 
  return Future.value(a * a * a);

Solución 3: método asincrónico

Un async El método devuelve automáticamente un Future para que puedas marcar el método async y cambie el tipo de retorno así:

Future cubed(int a) async 
  return a * a * a;

Normalmente usas async en combinación con await, pero no hay nada que diga que debes hacer eso. Dart convierte automáticamente el valor de retorno en un Future.

En el caso de que esté utilizando otra API que devuelva un Future dentro del cuerpo de su función, puede utilizar await al igual que:

Future cubed(int a) async 
  return await cubedOnRemoteServer(a);

O esto es lo mismo usando el Future.then sintaxis:

Future cubed(int a) async 
  return cubedOnRemoteServer(a).then((result) => result);

Solución 4: Completador

Usando un Completer es la solución de nivel más bajo. Solo necesita hacer esto si tiene alguna lógica compleja que las soluciones anteriores no cubren.

import 'dart:async';

Future cubed(int a) async 
  final completer = Completer();
  if (a < 0) 
    completer.completeError(ArgumentError("'a' must be positive."));
   else 
    completer.complete(a * a * a);
  
  return completer.future;

Este ejemplo es similar a la solución de constructor nombrada anteriormente. Maneja los errores además de completar el futuro de la forma habitual.

Una nota sobre el bloqueo de la interfaz de usuario

No hay nada en el uso de un futuro que garantice que no bloqueará la interfaz de usuario (es decir, el aislamiento principal). Devolver un futuro de su función simplemente le dice a Dart que programe la tarea al final de la cola de eventos. Si esa tarea es intensiva, seguirá bloqueando la interfaz de usuario cuando el bucle de eventos la programe para su ejecución.

Si tiene una tarea intensiva que desea ejecutar en otro aislado, debe generar un nuevo aislado para ejecutarlo. Cuando la tarea se complete en el otro aislado, devolverá un mensaje como futuro, que puede transmitir como resultado de su función.

Muchas de las clases estándar de Dart IO (como File o HttpClient) tienen métodos que delegan el trabajo al sistema y, por lo tanto, no realizan su trabajo intensivo en el hilo de la interfaz de usuario. Por lo tanto, los futuros que devuelven estos métodos están a salvo de bloquear su interfaz de usuario.

Ver también

  • Documentación de soporte de asincronía
  • Flutter Future vs Completer

Aquí puedes ver las reseñas y valoraciones de los usuarios

Si te ha resultado provechoso este post, sería de mucha ayuda si lo compartes con más programadores y nos ayudes a dar difusión a este contenido.

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)


Tags :

Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *