Javascript 使用异步库组装数据库中的所有标记
我正在使用sails.js创建一个标记系统,该系统与名为Javascript 使用异步库组装数据库中的所有标记,javascript,node.js,asynchronous,collections,sails.js,Javascript,Node.js,Asynchronous,Collections,Sails.js,我正在使用sails.js创建一个标记系统,该系统与名为Post的实体具有多对多关系。我进行关联的方法是使用数据库表将每个tagId与postId关联起来。每个帖子可以有多个标签 在检索到{tagId:'tagId,postId:'postId'}对象数组之后,我需要检索每个tagId的标记名。我使用的是async库,但是标记名(String)数组返回一个空的,从日志信息中,我可以看到返回发生在迭代器函数完成之前。我的代码如下: var tagIdPostIds = [ {tagId : 'ab
Post
的实体具有多对多关系。我进行关联的方法是使用数据库表将每个tagId
与postId
关联起来。每个帖子可以有多个标签
在检索到{tagId:'tagId,postId:'postId'}
对象数组之后,我需要检索每个tagId
的标记名。我使用的是async
库,但是标记名(String)数组返回一个空的,从日志信息中,我可以看到返回发生在迭代器函数完成之前。我的代码如下:
var tagIdPostIds = [
{tagId : 'abcx', postId: 1},
{tagId : 'abce', postId: 1},
{tagId : 'abcd', postId: 1},
];
if (tagIdPostIds) {
var tagsArr = []; //container of tag names
var findTagById = function(tagIdPostIdObj, cb) {
var tagId = tagIdPostIdObj.tagId;
Tag.findOneById(tagId, function (err, foundTag) {
if (err) return sendErrorMsgCode(res, "error in retrieving a tag", 401);
if (foundTag) {
sails.log.info('pushing in tag: ' + foundTag.tagName);
tagsArr.push(foundTag.tagName);
}
});
cb(); //without this, the program just hangs, but why??
}; //findTagById
var retTagNames = function(err) {
if (err) return sendErrorMsgCode(res, "error in assembling tag names", 401);
sails.log.info('returning tagsArr: ' + JSON.stringify(tagsArr));
return res.json(tagsArr);
}; //retTagNames
async.eachSeries(tagIdPostIds, findTagById, retTagNames);
}
在阅读了async
的文档之后,我认为async.map()
可能是为给定的postId
组装所有标记所需要的。或者我使用async.eachSeries()
的方法是错误的
感谢您的帮助我只是想把@Ben的答案加入到他上面的评论中,以便其他人可以轻松找到适合我的答案:
var tagIdPostIds = [
{tagId : 'abcx', postId: 1},
{tagId : 'abce', postId: 1},
{tagId : 'abcd', postId: 1},
];
if (tagIdPostIds) {
var tagsArr = []; //container of tag names
var findTagById = function(tagIdPostIdObj, cb) {
var tagId = tagIdPostIdObj.tagId;
Tag.findOneById(tagId, function (err, foundTag) {
if (err) return sendErrorMsgCode(res, "error in retrieving a tag", 401);
if (foundTag) {
sails.log.info('pushing in tag: ' + foundTag.tagName);
tagsArr.push(foundTag.tagName);
}
cb(); //this must be placed inside an async call to make it work!
});
}; //findTagById
var retTagNames = function(err) {
if (err) return sendErrorMsgCode(res, "error in assembling tag names", 401);
sails.log.info('returning tagsArr: ' + JSON.stringify(tagsArr));
return res.json(tagsArr);
}; //retTagNames
async.eachSeries(tagIdPostIds, findTagById, retTagNames);
}
在if(foundTag){…}之后需要在Tag.findOneById()内部调用cb(),这神奇地解决了问题。在if(foundTag){}块之后调用cb()的秘密是什么?感谢您,因为Tag.findOneById()是异步的,所以当cb()在外部时,它会通知eachSeries()继续循环并进入retTagNames(),而不是等待所有迭代完成后再进入retTagNames()