2016-02-04 60 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