He leído sobre el patrón de eliminador de promesas en varios lugares, pero no puedo entender qué es. Me sugirieron que lo usara en un código que se ve así:
function getDb(){ return myDbDriver.getConnection(); } var users = getDb().then(function(conn){ return conn.query("SELECT name FROM users").finally(function(users){ conn.release(); }); });¿Cuál es el patrón de eliminador de promesas y cómo se aplica aquí?
Nota: en las promesas nativas, .finally como "agregar controladores de rechazo y cumplimiento que devuelvan el valor pero realicen una acción". Estoy usando bluebird en este caso si importa.
El problema con el enfoque anterior es que si olvida liberar la conexión después de cada vez que ejecuta getDb , tiene una fuga de recursos que podría congelar su aplicación eventualmente cuando se quede sin el recurso que está filtrando.
Usted podría, en un lugar hacer:
var users = getDb().then(function(conn){ return conn.query("SELECT name FROM users"); });Lo que filtrará una conexión de base de datos que nunca se cerró.
El patrón de eliminación es una forma de acoplar un ámbito de código con la propiedad del recurso. Al vincular el recurso a un ámbito, nos aseguramos de que siempre se libere cuando hayamos terminado y no podamos olvidarnos fácilmente de liberarlo. Es similar al using en C#, with Python y Try-with-Resource en Java, así como RAII en C++.
Parece que:
withResource(function(resource){ return fnThatDoesWorkWithResource(resource); // returns a promise }).then(function(result){ // resource disposed here });Si escribimos nuestro código como:
function withDb(work){ var _db; return myDbDriver.getConnection().then(function(db){ _db = db; // keep reference return work(db); // perform work on db }).finally(function(){ if (_db) _db.release(); }); }Podríamos escribir nuestro código anterior como:
withDb(function(conn){ return conn.query("SELECT name FROM users"); }).then(function(users){ // connection released here });Ejemplos de usuarios del patrón disposer son sequelize y knex (constructor de consultas de estantería). También es posible usarlo para cosas más simples, como ocultar un cargador cuando se completaron todas las solicitudes de AJAX, por ejemplo.