助手的一個常見用途是封裝一些重複的資料庫查詢。例如,假設我們的應用程式有一個 User
模型,其中包含一個追蹤使用者上次登入時間的欄位 lastActiveAt
。在這樣的應用程式中,一個常見的任務可能是檢索最近上線的使用者列表。與其將此查詢硬編碼到多個位置,不如編寫一個助手來代替
// api/helpers/get-recent-users.js
module.exports = {
friendlyName: 'Get recent users',
description: 'Retrieve a list of users who were online most recently.',
extendedDescription: 'Use `activeSince` to only retrieve users who logged in since a certain date/time.',
inputs: {
numUsers: {
friendlyName: 'Number of users',
description: 'The maximum number of users to retrieve.',
type: 'number',
defaultsTo: 5
},
activeSince: {
description: 'Cut-off time to look for logins after, expressed as a JS timestamp.',
extendedDescription: 'Remember: A _JS timestamp_ is the number of **milliseconds** since [that fateful night in 1970](https://en.wikipedia.org/wiki/Unix_time).',
type: 'number',
defaultsTo: 0
}
},
exits: {
success: {
outputFriendlyName: 'Recent users',
outputDescription: 'An array of users who recently logged in.',
},
noUsersFound: {
description: 'Could not find any users who logged in during the specified time frame.'
}
},
fn: async function (inputs, exits) {
// Run the query
var users = await User.find({
active: true,
lastLogin: { '>': inputs.activeSince }
})
.sort('lastLogin DESC')
.limit(inputs.numUsers);
// If no users were found, trigger the `noUsersFound` exit.
if (users.length === 0) {
throw 'noUsersFound';
}
// Otherwise return the records through the `success` exit.
return exits.success(users);
}
};
若要從應用程式碼中使用預設選項呼叫此助手(例如,在動作中),我們可以使用
var users = await sails.helpers.getRecentUsers();
若要變更傳回使用者的條件,我們可以傳入一些值
var users = await sails.helpers.getRecentUsers(50);
或者,若要取得自 2017 年聖派翠克節以來登入的 10 位最新使用者
await sails.helpers.getRecentUsers(10, (new Date('2017-03-17')).getTime());
注意:這些在執行時傳遞到助手的值有時稱為 argins 或選項,它們與助手宣告的輸入定義的鍵順序相對應(例如
numUsers
和activeSince
)。
再次,鏈式調用 .with()
以使用具名參數
await sails.helpers.getRecentUsers.with({
numUsers: 10,
activeSince: (new Date('2017-03-17')).getTime()
});
最後,若要明確處理 noUsersFound
退出,而不是僅僅將其視為任何其他錯誤,我們可以使用 .intercept()
或 .tolerate()
var users = await sails.helpers.getRecentUsers(10)
.tolerate('noUsersFound', ()=>{
// ... handle the case where no users were found. For example:
sails.log.verbose(
'Worth noting: Just handled a request for active users during a time frame '+
'where no users were found. Anyway, I didn\'t think this was possible, because '+
'our app is so cool and popular. But there you have it.'
);
});
var users = await sails.helpers.getRecentUsers(10)
.intercept('noUsersFound', ()=>{
return new Error('Inconceivably, no active users were found for that timeframe.');
});
使用助手的主要優點是能夠通過在單個位置更改程式碼來更新應用程式許多部分的功能。例如,通過將 numUsers
的預設值從 5
更改為 15
,我們可以更新任何使用該助手的地方傳回的預設列表的大小。此外,通過使用像 numUsers
和 activeSince
這樣定義完善的輸入,我們可以保證在意外使用無效(即非數字)值時獲得有用的錯誤訊息。
關於上面的 getRecentUsers()
助手範例的更多注意事項
- 許多欄位(例如
description
和friendlyName
)不是嚴格要求的,但對於保持程式碼可維護性非常有幫助,尤其是在跨多個應用程式共享助手時。noUsersFound
退出可能有幫助,也可能沒有幫助,具體取決於您的應用程式。如果您始終希望在沒有使用者傳回時執行特定操作(例如,重新導向到不同的頁面),則此退出將是一個好主意。另一方面,如果您只是想根據是否傳回使用者來調整視圖中的一些文字,則最好只使用success
退出,並在您的動作或視圖程式碼中檢查傳回陣列的length
。