2016-02-04 22 views
0

我是新来的Node.js,所以如果我的问题听起来有点愚蠢,我很抱歉。Node.js:我如何编写一个“异步”的获取器

这里是我走向:

我设计对象的其中一个属性必须通过数据库查询来设置。为了这个任务,我要求promise-mysql。为了将属性提供给其他对象,我希望有一个getter,用于检查属性是否设置的天气,后者在返回其值之前从数据库加载属性。

我迄今为止的做法:

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

到目前为止,如果属性尚未设置/加载但吸气返回一个承诺对象。我可以在调用函数中使用...... then()来处理这个承诺对象,但是我希望getter能够阻止返回值,直到承诺解决。这甚至有可能吗?

问候 格雷格

回答

2

你的接口应该可能只是始终返回一个承诺。然后来电者可以这样做:

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

一个理由做这种方式是,你不想呼叫者必须知道或做不同的事情,如果财产被获取或异步已经缓存。为两者提供相同接口的唯一方法是使接口始终是异步的,只是返回承诺会自动给你。在您显示的代码中,您使用.catch()来记录错误,但不会重新抛出错误。那将“默默地”吃掉错误,并且不会返回给调用者。调用者将看到一个已履行的承诺,其值为undefined。如果你想为记录原因做你自己的.catch(),那么你必须重新抛出错误(或返回一个被拒绝的承诺),以确保它传回给调用者。所有本身没有返回值的公司都会将承诺变为已解决的承诺,因为它假定您已经处理了错误。

+0

许多thx为您的解释(和重新抛出错误的建议)。我现在清楚地看到:没有办法让getter“保留”返回值,而是必须调整调用者。 – Greg