助手的一个常见用途是封装一些重复的数据库查询。例如,假设我们的应用程序有一个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
。