【问题标题】:How to dispose resources in rejected promises with bluebird?如何使用蓝鸟处理被拒绝的承诺中的资源?
【发布时间】:2016-01-06 05:26:43
【问题描述】:

当promise被拒绝时,我该如何处理serial?

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

未处理的拒绝类型错误:无法调用方法“isOpen”的 未定义

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

【问题讨论】:

  • 没有足够的上下文(或问题)来回答这个问题。一个明显的缺陷是端口必须是 undefined 某处才会发生该错误。
  • 您说“...处置序列...”但dispose() 接受port。是哪个?
  • 是的,抱歉命名不当。我最终删除了 bluebird 并改用回调。

标签: javascript node.js serial-port promise bluebird


【解决方案1】:

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

考虑到这种模式,您会发现在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() 返回的承诺数组做更多事情,但这是另一个问题。

【讨论】:

    猜你喜欢
    • 2015-04-07
    • 2015-04-13
    • 2015-05-17
    • 2018-09-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多