【发布时间】:2016-10-12 16:48:04
【问题描述】:
我正在使用一个 API 包装器,其端点在查询时只接受用户 ID - 但是,有一个端点可以让我按用户名搜索(包装器 searchByUsername,您将在下面看到使用)我写了以下帮助函数在每个请求触发之前转换它们,为我们的用户提供灵活性:
var convertToID = function (username, callback) {
searchByUsername(username, function (error, response, body) {
if (body.users[0]){
callback(body.users[0].username)
}
})
};
我是这样使用它的:
this.relationship = function (user, query, callback) {
if (isNaN(user)) {
convertToID(user, function (ID) {
get('/users/' + ID + '/relationships/?query=' + query, callback);
})
} else {
get('/users/' + user + '/relationships/?query=' + query, callback);
}
}
这很好用,但是将它放入我的每个包装器中显然不是最佳选择。来自 Ruby 背景,我可以将其浓缩为一行 - 但 JS 的异步性质有点扭曲我的大脑。我真正想要的是类似的东西:
var user = isNaN(user) ? convertUsernameToID(user) : user;
get('/users/' + user + '/relationships/?query='+query, callback);
我已经探索了其他答案(是的,我知道有很多答案)re: async JS gotchas,但我一定遗漏了一些东西。在过去的大型项目中,我使用过 async 包,但感觉有点矫枉过正,我更愿意真正了解它。
【问题讨论】:
-
你看过promise吗?
-
您的
convertToID函数似乎不能很好地处理错误(或根本没有)。你真的应该看看 promises。 -
@Bergi 是的,我接触过 bluebird 和一点 ES6 承诺。我实际上记得在那里遇到过类似的问题,那就是我仍然无法从嵌套函数返回值。所以我仍然无法实现上述单线解决方案 - 除非我只是误解了它们。我的头是不是太卡在 Ruby 领域了?
-
@Bergi 是的,这只是一个粗略的草图来充实它。这真是令人畏惧......我在发布之前就有这样的想法。
-
使用带有 promise 的 async/await(来自 ES8),实际上您也可以在 JS 中将其简化为单线:
async function relationship(user, query) { return get('/users/' + (isNaN(user) ? await convertUsernameToID(user) : user) + '/relationships/?query=' + query); }
标签: javascript node.js asynchronous