javascript - 如何使用 Bluebird 处理被拒绝的 promise 中的资源?

标签 javascript node.js serial-port promise bluebird

当 promise 被拒绝时,我该如何处置序列号?

dispose 函数会打印被拒绝​​的 Promise 的错误。

Unhandled rejection TypeError: Cannot call method 'isOpen' of 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);
}();

最佳答案

这个问题几乎可以回答自己,因为“ promise ”和“处置”一起恳求您考虑 Promise Disposer Pattern ,这实际上只不过是明智地使用 .then().finally() 以及回调来处理/关闭之前创建/打开的内容。

考虑到这种模式,您会发现在 pingPort() 中协调处理比 findPort() 更简单。

假设问题中的代码大致正确,您可以按如下方式链接finally():

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".
    });
};

与 .then 不同,.finally 的处理程序不会修改值/原因,因此可以放置在中间链中,而无需担心返回值或重新抛出错误。 Bluebird 文档中对这一点的阐述相当糟糕。

通过在 pingPort() 中进行处理,findPort() 将简化如下:

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);
        });
    });
}();

更进一步,您可能希望对 .map() 返回的 promise 数组执行更多操作,但这是另一个问题。

关于javascript - 如何使用 Bluebird 处理被拒绝的 promise 中的资源?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33018352/

相关文章:

javascript - 如何在进度条全屏表单界面上添加百分比状态

windows - Rust Serialport-RS 读取被阻止

javascript - Django 1.7 w/AJAX,如何或在哪里清理要在 AJAX 请求中传递的输入

Javascript 在第一次出现数字时分割一次

java - 在 Java 中创建一个 JSON 对象并在 javascript/jquery 中访问它

bash - 如何让 Cloud9 IDE 在后台运行?

node.js - 禁用 Mongoose 架构中的插件

javascript - ExpressJS 4.2 和 flash 错误(TypeError : Object #<IncomingMessage> has no method 'flash' )

c++ - 如何使 boost::asio::serial_port_base::flow_control 使用硬件流控制?

C串口读取未发现回车 "\r"