什么是Promise处理器模式?

IT技术 javascript promise dispose bluebird
2021-02-02 06:32:36

我在几个地方读过关于 promise 处理程序模式的内容,但我不知道它是什么。有人建议我在如下代码中使用它:

function getDb(){
    return myDbDriver.getConnection();
}

var users = getDb().then(function(conn){
     return conn.query("SELECT name FROM users").finally(function(users){
         conn.release();
     });
});

什么是 promise 处理程序模式以及它在此处如何应用?


注意 - 在本机Promise中,我填充.finally为“添加返回值但执行操作的拒绝和履行处理程序”。如果重要的话,我在这种情况下使用蓝鸟。

1个回答

你的代码的问题

上述方法的问题在于,如果您在每次执行后忘记释放连接,您getDb就会发生资源泄漏,当您泄漏的资源用完时,最终可能会冻结您的应用程序。

您可能会在一个地方执行以下操作:

var users = getDb().then(function(conn){
     return conn.query("SELECT name FROM users");
});

这将泄漏从未关闭的数据库连接。


处理器模式

处置器模式是一种将代码范围与拥有资源耦合的方式。通过将资源绑定到一个作用域,我们可以确保它在我们完成后总是被释放,并且我们不会轻易忘记释放它。它类似于usingC#、withPython 和 Java 中的 try-with-resource 以及 C++ 中的 RAII。

看起来像:

 withResource(function(resource){
     return fnThatDoesWorkWithResource(resource); // returns a promise
 }).then(function(result){
    // resource disposed here
 });

在这里应用

如果我们将代码编写为:

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

我们可以把上面的代码写成:

 withDb(function(conn){
     return conn.query("SELECT name FROM users");
 }).then(function(users){
     // connection released here
 });

处置器模式的用户示例是sequelizeknex(书架的查询构建器)。也可以将它用于更简单的事情,例如在所有 AJAX 请求完成时隐藏加载程序。

蓝鸟

由于您使用的蓝鸟,它一直致力于Promise.using.disposer内置在功能,让你处理采取/一次你可能要考虑释放多个资源。

是的,你可能想崩溃,但有一个正确的例外,说明了连接问题:-)
2021-03-13 06:32:36
您是否有使用示例Promise.using,以与您的处理器模式进行比较?
2021-03-21 06:32:36
@Bergi 如果getConnection失败,您希望您的应用程序崩溃并烧毁(因为连接池数据库连接失败,而不是数据库上的操作),但我同意这应该是明确的 - 随时编辑或建议编辑。
2021-03-26 06:32:36
这安全吗?假设withDb()快速连续拨打了两个电话。这两个连接会完全独立吗?如果没有,那么您可能需要一种机制,仅当两个请求都得到满足时才释放其中一个连接。
2021-03-30 06:32:36
这不是缺少一个if (_db)吗?如果getConnection失败,当前withDb()将拒绝“无法调用未定义的发布”错误。
2021-04-03 06:32:36