我正在编写一些代码,它首先遍历数组,然后进一步遍历原始数组中包含的数组。
我结束了这种奇怪的模式,我正在重复,我确信它没有被优化。在迭代最后一个rssFeeds数组项时,它会将'triggerCallback'的值更改为true。稍后,在遍历item数组时,条件检查triggerCallback是否为true且items数组是否正在遍历其最后一项,此时它会触发回调以在async.js的瀑布模式中使用。
function countSuccessPosts(rssFeeds, cb){
var successCounter = 0;
var triggerCallback = ''
rssFeeds.forEach(function(feed, index, array){
if(index == array.length - 1){
triggerCallback = 'true'
}
feed.itemsToPost.forEach(function(item, itemIndex, itemArray){
if(item.response.id){
++successCounter
}
if(itemIndex == itemArray.length - 1 && triggerCallback == 'true'){
cb(null, rssFeeds, successCounter)
}
})
})
}
构建此模式的最佳方法是什么?
数据结构:RssFeeds最多包含5个不同的itemToPost元素。
[
{
"_id": "55808127b8f552c8157f74a7",
"name": "",
"imageUrl": "",
"url": "http://www.taxheaven.gr/bibliothiki/soft/xml/soft_law.xml",
"latestDate": "1434056400000",
"endpoints": [
{
"_id": "554f9319bc479deb1757bd2e",
"name": "Wise Individ",
"id": 26413291125,
"type": "Group",
"__v": 0
}
],
"__v": 1,
"itemsToPost": [
{
"title": "Aριθμ.: Υ194/12.6.2015 Τροποποίηση απόφασης ανάθεσης αρμοδιοτήτων στον Αναπληρωτή Υπουργό Οικονομικών Δημήτριο Μάρδα.",
"summary": "Τροποποίηση απόφασης ανάθεσης αρμοδιοτήτων στον Αναπληρωτή Υπουργό Οικονομικών Δημήτριο Μάρδα.",
"url": "http://www.taxheaven.gr/laws/circular/view/id/21113",
"published_at": 1434056400000,
"time_ago": "5 days ago",
"guid": {
"link": "http://www.taxheaven.gr/laws/circular/view/id/21113",
"isPermaLink": "true"
}
}
]
},
{
"_id": "558093013106203517f96d9c",
"name": "",
"imageUrl": "",
"url": "http://www.taxheaven.gr/bibliothiki/soft/xml/soft_new.xml",
"latestDate": "1434489601236",
"endpoints": [],
"__v": 0,
"itemsToPost": [
{
"title": "Taxheaven - Άμεση ενημέρωση - Έγκαιρη επιστημονική κωδικοποίηση - Καινοτομικά εργαλεία. Κωδικοποιήθηκαν όλοι οι νόμοι στους οποίους επιφέρει αλλαγές ο νόμος 4330/2015",
"summary": {},
"url": "http://www.taxheaven.gr/news/news/view/id/24088",
"published_at": 1434494400000,
"time_ago": "about 4 hours ago",
"guid": {
"link": "http://www.taxheaven.gr/news/news/view/id/24088",
"isPermaLink": "true"
}
}
]
}
]
答案 0 :(得分:2)
我没有检查过这个,但它与我目前在我的项目中使用的非常相似:
function countSuccessPosts(rssFeeds, cb){
async.each(rssFeeds, function(eachFeed, outerCallback) {
async(eachFeed.itemToPost, function(eachItem, innerCallback) {
if(item.response.id) {
//Do Something That Is Actually Async. Could be asking the server for success flag, for instance.
doSomethingThatIsActuallyAsync(item.response.id).then(function (err) {
if (!err) {
successCounter = successCounter + 1;
}
innerCallback();
});
} else { //This could be to skip "empty responses" without the need to go to the server, right?
innerCallback();
}
}, outerCallback);
}, function() {
//All done
cb(null, rssFeeds, successCounter);
});
}
正如其他人所提到的,只有在内部循环中有实际的异步方法调用时才需要这个。
答案 1 :(得分:0)
您不需要跟踪最后一项。只需在两个循环退出后调用回调。我还将AbstractRoutingDataSource
更改为for循环,因为它们执行得更快。
.forEach
当然,如果您在没有回调的情况下调用function countSuccessPosts(rssFeeds, cb) {
var index, itemIndex, feed, item;
for (index = 0; index < rssFeeds.length; index++) {
feed = rssFeeds[index];
for (itemIndex = 0; itemIndex < feed.itemsToPost.length; itemIndex++) {
item = feed.itemsToPost[itemIndex];
if(item.response && item.response.id) {
successCounter++;
}
}
}
cb(null, rssFeeds, successCounter);
}
,则调用代码可能如下所示:
countSuccessPosts
您可以将函数重新格式化为:
var successPosts = countSuccessPosts(rssFeeds);
答案 2 :(得分:0)
等等,当你可以同步读取数据时,为什么要使用回调?
在您更新了问题之后,看起来您只是在总结一个问题 数组中元素的数量
这是一个完全同步的版本,用于计算有效itemsToPost
集的response.id
的数量。
function countSuccessPosts(rssFeeds) {
return rssFeeds.reduce(function(sum, x) {
return sum + x.itemsToPost.filter(function(y) {
return !!y.response.id;
}).length;
}, 0);
}
如果您需要将此注入到异步控制流中,您可以轻松地在其上放置一个包装器
function(rssFeeds, done) {
done(null, rssFeeds, countSuccessPosts(rssFeeds));
}
关键是,countSuccessPosts
具有同步API,因为该函数中发生的所有内容都是同步。