> Manuales > Manual de Lit

Qué significa que Lit implemente updates asíncronos en los templates. Cómo puede afectar en el desarrollo de componentes. Utilizar la propiedad updateComplete de los componentes, una promesa que se resuelve al terminar de actualizar el template.

Updates asíncronos del template en componentes Lit y updateComplete

Otro aspecto que debe quedar claro con lo que respecta a Lit y las actualizaciones automáticas de los templates es que se realizan de manera asíncrona. Esto es así por motivos de rendimiento y para asegurarse que las actualizaciones del template sean las mínimas necesarias.

En este artículo veremos qué significa esto y cómo nos puede afectar. Además, de paso, aprenderemos a usar otras herramientas para controlar el ciclo de vida de componentes Lit, en este caso la propiedad updateComplete.

Para explicar el tema de los updates asíncronos de los templates en componentes Lit vamos a tocar estos puntos.

Qué significa que las actualizaciones son asíncronas

A estas alturas espero que ningún lector desconozca el significado del término "asíncrono", tan esencial en Javascript. De todos modos, en resumen, puedo decir que básicamente indica que una tarea puede llevar un tiempo en ejecutarse y durante este tiempo no se bloqueará el flujo de ejecución de Javascript.

Hay toda una categoría de Javascript asíncrono y si necesitas una lectura rápida te recomiendo esta FAQ sobre qué es Javascript asíncrono.

En concreto en lo que respecta al ciclo de actualizaciones de los templates en Lit, el hecho de ser asíncrono quiere decir que las actualizaciones del template no se realizan inmediatamente como consecuencia de un cambio, sino que se podrá demorar un poco más. Usualmente el tiempo de demora es inapreciable, pero esto ayuda a mejorar el rendimiento si, por ejemplo se modifican dos o más propiedades al mismo tiempo.

Por ejemplo, mira este método que cambia dos propiedades que vamos a suponer que son reactivas.

cambioRandom() {
    this.prop1 = Math.random();
    this.prop2 = Math.random();
}

En este caso se van a ejecutar dos sentencias seguidas. Si el ciclo de las actualizaciones de un template no fuera asíncrono querría decir que se actualizaría dos veces el template, una para cada una de las propiedades que se han modificado. Quizás dos actualizaciones no tarden tanto tiempo, pero imaginemos que tenemos decenas de propiedades que se cambian a la vez. En ese caso estaríamos ante una posible carencia de rendimiento ya que el template se actualizaría decenas de veces, cuando hubiera sido mejor una única actualización después de que todas las propiedades del componente hayan cambiado.

Propiedad updateComplete de Lit

En la mayoría de las ocasiones, el hecho de que las actualizaciones del template sean asíncronas no te afecta en nada. Por tanto, a la hora de desarrollar un componente puedes simplemente olvidar esta característica. Igualmente, en términos de experiencia de usuario, se observará que todo funciona de manera muy rápida y no se llegará a percibir ningún efecto en particular debido a la asincronía.

Sin embargo, hay algunas ocasiones en las que el hecho de tener cambios asíncronos en el template puede sí puede afectarnos. Cuando esto ocurra podemos usar mano de la propiedad updateComplete, que contiene una promesa que se resuelve solamente cuando el template ha sido actualizado.

Funciona de la siguiente manera:

this.prop1 = 'cambio la propiedad reactiva';
this.updateComplete
        .then(() => console.log('El template se ha actualizado'));

Este código nos asegura que, una vez se está ejecutando el "then", porque la promesa updateComplete() se haya resuelto, tenemos la garantía de que el template ha actualizado la vista del componente, reflejando todos los valores de las propiedades reactivas que hayan cambiado.

Dónde podemos sacar partido de updateComplete

Por ejemplo en las pruebas unitarias. Podemos hacer cambios en las propiedades de un componente y esperar al updateComplete, para una vez se ha producido hacer consultas a su DOM, para ver si está correctamente compuesto, con los valores que cabía esperar.

Como decía, en la práctica del desarrollo de componentes es poco común que lo necesitemos por lo que quizás el ejemplo que vamos a ver es un poco rebuscado.

Observa este template:

render() {
    return html`
        <dw-collection-service
            entity="${this.entity}"
            @dw-collection-success="${this.onSuccess}"
            @dw-collection-error="${this.onError}"
        ></dw-collection-service>
        <button @click=${this.showComments}>Recibe Comentarios</button>
        <pre>${JSON.stringify(this.json)}</pre>
    `;
}

Estamos haciendo uso de un componente llamado dw-collection-service, cuyo código veremos enseguida. El caso es que este componente hace unas consultas ajax para recibir una entidad de un servicio web.

La entidad a la que queremos consultar la pasamos al componente, mediante el atributo "entity".

Podríamos suponer que para hacer una consulta a este servicio sería suficiente hacer esto:

showComments() {
    this.entity = 'comments';
    this.shadowRoot.querySelector('dw-collection-service').getData();
}

Quizás este modo de trabajar pueda resultar perfectamente lógico y pensemos que va a funcionar sin problemas, pero el caso es que no tiene por qué ser así, debido justamente a las actualizaciones asíncronas del template.

Esta situación la podemos resolver simplemente así:

showComments() {
    this.entity = 'comments';
    this.updateComplete
        .then(() => this.service.getData());
}

En vez de invocar de seguido a getData() vamos a esperar a que el template se haya actualizado, para garantizar que la propagación del nuevo valor del atributo entity haya llegado al componente dw-collection-service.

Espero que la situación se haya podido entender y que se aprecie la utilidad de updateComplete en este ejemplo.

Código de los componentes que hemos usado para este ejemplo

No me quiero liar explicando el detalle de los componentes que he usado para este ejemplo, ya que nos iríamos del tema que nos interesaba, pero sí te voy a dar la URL del repositorio donde los encuentras.

https://github.com/deswebcom/manual-lit

Cualquier duda nos puedes preguntar. En el Curso de Lit de EscuelaIT están explicados con detalle estos componentes y los hemos realizado paso a paso.

Pausa en el manual

De momento vamos a hacer una pausa en el Manual de Lit. Hemos cubierto muchos temas que estamos seguros que os han llevado a un buen nivel en el desarrollo de Lit. Hemos hecho cantidad de ejemplos de compoentes y esperamos que le hayáis tomado el gustito a desarrollar con esta librería basada en Web Components.

A partir de aquí se trata de usar estos componentes en cualquier tipo de proyecto. Si te ha gustado el manual y quieres aprender más te comento que en el Curso de Lit mencionado antes que impartí en EscuelaIT tienes mucho más material y ejempos para llegar aún más lejos.

Miguel Angel Alvarez

Fundador de DesarrolloWeb.com y la plataforma de formación online EscuelaIT. Com...

Manual