Node.js: 如何写 "asynchronous" getter

Node.js: How do I write an "asynchronous" getter

我是 Node.js 的新手,如果我的问题听起来有些愚蠢,请见谅。

这是我要去的地方:

我正在设计一个对象,其中 属性 必须通过数据库查询来设置。对于此任务,我需要 promise-mysql。为了向其他对象提供 属性,我想要一个 getter 来检查是否设置了 属性 并在后者中加载 属性 来自returning 其值之前的数据库。

我目前的方法:

MyObject = function () 
{
    this._property = null;
};

MyObject.prototype._loadProperty = function() 
{
    var self = this;
    return pool.query('SELECT * FROM table WHERE condition = ?', [condition]).then(function(rows)
     {
         return self._property = rows;
     }).catch(function(err) 
     {
         console.log(err);
     });
 };

 MyObject.prototype._getProperty = function()
 {
     return this._property || this._loadProperty();
 }

到目前为止,如果 属性 尚未 set/loaded,则 getter 正在 return 承诺对象。我可以在调用函数中使用 ...then() 处理此 promise 对象,但我希望 getter 保留 return 值,直到 promise 解决。这可能吗?

问候 格雷格

您的界面可能应该总是 return 一个承诺。然后调用者可以这样做:

 this.getProperty().then(...)

无论 属性 之前是否被缓存,它们的界面都是相同的。


事实上,您甚至可以在内部使用 promise 作为缓存机制。

MyObject = function () {
    this._propertyPromise = null;
};

MyObject.prototype._loadProperty = function () {
    var self = this;
    return pool.query('SELECT * FROM table WHERE condition = ?', [condition]).catch(function (err) {
        console.log(err);
        throw err;             // propagate reject error back to caller
    });
};

MyObject.prototype.getProperty = function () {
    if (!this._propertyPromise) {
        this._propertyPromise = this._loadProperty();
    }
    return this._propertyPromise;
}

这样做的一个原因是如果 属性 被异步获取或已经被缓存,您不希望调用者必须知道或做任何不同的事情。为两者提供相同界面的唯一方法是使界面始终是异步的,只需 return 承诺即可自动为您提供。

仅供参考,在您显示的代码中,您使用 .catch() 记录错误,但没有重新抛出错误。那会 "silently" 吃掉错误并且不会 return 返回给调用者。调用者会看到一个具有 undefined 值的 fulfilled promise。如果出于日志记录的原因你想自己做 .catch(),那么你必须重新抛出错误(或 return 被拒绝的承诺)以确保它传播回调用者。 .catch() 本身没有 return 值只会将承诺更改为已解决的承诺,因为它假定您已经处理了错误。