Quiero crear una función que devuelva un futuro. Un valor se resolverá en un momento específico. Sin embargo, el valor deberá resolverse desde dentro de una devolución de llamada. En Javascript, podría hacer algo como esto:
function delay(seconds) { return new Promise((resolve, reject) => { setTimeout(resolve, seconds * 1000); }); }No veo ninguna solución clara para esto en Dart, ¿alguien podría mostrarme una forma de hacerlo (o una forma de evitarlo)? Si necesita alguna aclaración, no dude en hacer un comentario.
Editar: para ser más claro, proporcionaré el contexto y el código fuente que he creado.
Estoy tratando de hacer una función (método, en realidad) que regrese después de que le ocurra un solo evento a un elemento. Primero lo escribí en Javascript -
HTMLElement.prototype.on = function(eventName) { return new Promise(function(resolve, reject) { var handler = function(event) { resolve(null); this.removeEventListener(eventName, handler); }; this.addEventListener(eventName, handler); }); }; y puedes usarlo así: await myButton.on("click"); alert("Button clicked first time"); .
Estoy tratando de recrearlo en Dart + HTML por jugar, y aquí está el código hasta ahora.
import "dart:html"; extension on HtmlElement { on(String name) { void handler(Event event) { removeEventListener(name, handler); // Do something to actually return from the method... } addEventListener(name, handler); } } void main() {}Edit: para los curiosos, el código completo se puede encontrar aquí o aquí .
No estoy familiarizado con JavaScript Promise s, pero suponiendo que desea await myButton.on("click") se complete solo después de que la función del handler se haya ejecutado al menos una vez, puede usar un Completer :
import "dart:async"; import "dart:html"; extension on HtmlElement { Future<void> on(String name) { final completer = Completer<void>(); void handler(Event event) { removeEventListener(name, handler); completer.complete(); } addEventListener(name, handler); return completer.future; } }Una promesa se puede resolver una vez como máximo, por lo que probablemente tenga sentido eliminar automáticamente el detector de eventos después del primer clic. Y en lugar de modificar el HtmlElement.prototype que es una práctica antihigiénica, escriba una función de clic simple que acepte un onclick como entrada:
function onclick(elem) { return new Promise(r => elem.addEventListener("click", r, {once: true}) ) } function main () { onclick(document.forms.myapp.mybutton) .then(event => console.log(event.target)) onclick(document.forms.myapp.otherbutton) .then(event => console.log(event.target)) } main() <form id="myapp"> <button type="button" name="mybutton">A</button> <button type="button" name="otherbutton">B</button> </form>