sincronas promesas node funciones entre ejecucion diferencia controlar asincrono asincronia asincrona anidadas javascript node.js serial-port promise bluebird

javascript - promesas - node js asincrono



¿Cómo disponer los recursos en las promesas rechazadas con bluebird? (1)

¿Cómo puedo disponer el serial cuando se rechaza la promesa?

La función de eliminación imprime el error para las promesas rechazadas.

Rechazo no manejado TypeError: no se puede llamar al método ''isOpen'' de undefined

var pingPort = function(port){ return new promise(function(resolve, reject){ var serial = new com.SerialPort(port.comName, { baudrate: 19200, parser: com.parsers.readline(lineEnd) }, false); serial.on("data", function(data){ if (data === responseUuid){ resolve(serial); } }); serial.open(function(err){ if (err){ //reject(serial) } else{ serial.write(pingUuid + lineEnd); } }); }); }; var dispose = function(port){ console.log(port.isOpen()); }; var findPort = function(){ com.listAsync().map(function(port){ return pingPort(port).timeout(100).catch(promise.TimeoutError, function(err) { console.log("Ping timout: " + port.comName); dispose(port); }).catch(function(err){ console.log("Ping error: " + port.comName); dispose(port); }); }).each(dispose); }();


Esta pregunta casi se responde a sí misma, en esa "promesa" y "deseche" juntos le piden que considere el Patrón Promise Disposer , que en realidad no es más que el uso juicioso de .then() o .finally() con una devolución de llamada que se deshace / cierra algo que fue creado / abierto antes.

Con ese patrón en mente, le resultará más sencillo organizar el desecho en pingPort() lugar de findPort() .

Suponiendo que el código en la pregunta es ampliamente correcto, puede encadenar finally() siguiente manera:

var pingPort = function(port) { var serial; // outer var, necessary to make `serial` available to .finally(). return new promise(function(resolve, reject) { serial = new com.SerialPort(port.comName, { baudrate: 19200, parser: com.parsers.readline(lineEnd) }, false); serial.on(''data'', function(data) { if(data === responseUuid) { resolve(serial); //or resolve(port); } }); serial.open(function(err) { if(err) { reject(''failed to open''); } else { serial.write(pingUuid + lineEnd); } }); }) .finally(function() { // <<<<<<<<<<< serial.close(); // "dispose". }); };

A diferencia de .then, el controlador de .finally no modifica el valor / razón, por lo que puede colocarse en la mitad de la cadena sin la necesidad de preocuparse por devolver un valor o volver a generar un error. Este punto está bastante mal hecho en la documentación de Bluebird.

Con eliminación en pingPort() , findPort() se simplificará de la siguiente manera:

var findPort = function(){ com.listAsync().map(function(port) { return pingPort(port).timeout(100) .catch(promise.TimeoutError, function(err) { console.log("Ping timout: " + port.comName); }) .catch(function(err){ console.log("Ping error: " + port.comName); }); }); }();

Yendo más lejos, es posible que desee hacer más con la serie de promesas devueltas por .map() , pero ese es otro problema.