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 Future
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.