Recientemente me sumergí en las suscripciones de Subject/BehaviorSubject/ etc. y estoy buscando el enfoque goto cuando se usa en combinación con Promises.
A continuación se muestra el código de ejemplo:
firebase.user.subscribe((user: any | null) => { fs.readFile('path/to/file') .then((buf: Buffer) => { this.modifySomeData = buf; }); }); Me suscribo a un Asunto que se activa cada vez que el usuario inicia o cierra sesión en su servicio. Cada vez que esto sucede, leo un archivo del disco. Este evento readFile podría demorar potencialmente más que el siguiente evento de "inicio/cierre de sesión". Por supuesto, estoy en JS y en un entorno asíncrono. Esto significa que mi código de usuario no es multiproceso, pero aún así, el segundo evento de usuario y el segundo archivo de readFile podrían ser teóricamente más rápidos que el primer archivo de readFile .
El orden está mezclado. El enfoque más tonto que se me ocurrió es crear un uuid antes de leer el archivo y verificar dentro de la promesa si sigue siendo el mismo. Si no es así, descarto los datos.
¿Hay una solución mejor?
El primer enfoque es ver si su lógica de generación de eventos podría manejar la espera para el manejo de eventos. Por ejemplo, puede usar una promesa para esperar el evento O generar otro evento, decir doneReadFile y solo luego enviar el siguiente evento. Por lo general, este no es el caso de un entorno genérico (distribuido).
Si a la generación de eventos no le importa cuánto tiempo llevó manejar los eventos, aún puede usar el enfoque anterior, pero verifique el evento intermedio doneReadFile en el siguiente controlador de eventos (iniciar/cerrar sesión). Esto se puede lograr mediante la implementación de algún tipo de sondeo o ocupado-esperar/dormir
Si tengo un proceso en el que se pueden descartar solicitudes anteriores, a menudo mantengo una variable en el alcance para rastrear la última solicitud y comparar, similar a su idea de UUID:
let lastRead: Promise<Buffer> | null = null; firebase.user.subscribe((user: any | null) => { const read = lastRead = fs.readFile('path/to/file'); read.then((buf: Buffer) => { if (read != lastRead) return; this.modifySomeData = buf; }); }); En este caso específico, readFile también admite una señal de cancelación. Por lo tanto, es posible que también pueda abortar la última solicitud; Sin embargo, aún necesitará rastrearlo.