我的数据库中有几百个文档。架构非常简单:
var firmsSchema = mongoose.Schema({
name: String,
sections: [String],
});
我想查询文档并迭代:
{{#each sections}}
{{sectionName}}
{{#each firms}}
{{firmName}}
{{/each}}
{{/each}}
简单:
const SECTIONS = ['name_one', 'name_two', 'name_three'];
const UNSORTED_SECTION_NAME = 'unsorted';
router.get('/', function(req, res, next) {
var showFirms = function showSection (i, acc) {
if (i < 0) return;
let query = SECTIONS[i] ? {sections: SECTIONS[i]} : {sections: {$nin: SECTIONS}};
let key = SECTIONS[i] || UNSORTED_SECTION_NAME;
Firms.find(query).
then((result) => {
acc.push({
section: key,
firms: result,
});
if (i === SECTIONS.length) {
acc = acc.sort((a, b) => (a.section > b.section));
res.render('template', {
sections: acc,
});
}
}).
then(showSection (i - 1, acc));
}
showFirms(SECTIONS.length, []);
};
工作正常。除了它随机返回acc
并且不可预测地排序。我的意思是'name_two'
部分可以跟'name_one'
或反之亦然。
我认为承诺链末尾的.sort()
将是一个银弹并解决所有异步问题,但它没有。
当我把它传递给我的模板后,我可以用把手帮助对acc
进行排序,但是在我{{1}完成所有查询之后我无法对它进行排序是非常奇怪的。功能。
你能给我一些建议吗?
答案 0 :(得分:2)
看看你的代码重制。我们必须在同一时间(异步)获取数据,而不是逐个获取数据,然后处理返回。
如果您对此有任何疑问,此代码未经测试,请向我提供反馈。这是一个如何更改代码的示例。
const showFirms = function showSection() {
return new Promise((resolve, reject) => {
// Get the keys for the queries
const keys = SECTIONS.map(x => x || UNSORTED_SECTION_NAME);
// For each sections we gonna call a find request
const promises = SECTIONS.map((x, xi) => {
const query = x ? {
sections: x,
} : {
sections: {
$nin: SECTIONS,
},
};
const key = keys[xi];
return Firms.find(query);
});
// Resolve all promises
Promise.all(promises)
.then((rets) => {
// Use the finds results to build an acc array
const accs = rets.map((x, xi) => ({
section: keys[xi],
firms: x,
}));
// Change the sort -> ;) #comments
const sortedAccs = accs.sort((a, b) => (a.section > b.section));
resolve(sortedAccs);
})
.catch(reject);
});
};
如何使用
showFirms()
.then(accs => res.render('template', {
sections: accs,
}))
.catch(err => console.log(`I have an error ${err.toString()}`));
答案 1 :(得分:0)
基于GrégoryNEUTS的出色解决方案。我简化了一些事情并使“其他部分案例”工作。我甚至放弃了排序功能。最终结果按照在初始SECTIONS
数组中声明的部分的顺序返回,所以现在我可以重新排序它以控制输出。
const showFirms = function () {
return new Promise ((resolve, reject) => {
const extendedSections = SECTIONS.slice();
extendedSections.push(UNSORTED_SECTION_NAME);
const promises = extendedSections.map((section) => {
const unsortedCase = section === UNSORTED_SECTION_NAME;
const query = unsortedCase ? {sections: {$nin: SECTIONS}} : {sections: section};
return Firms.find(query);
})
Promise.all(promises)
.then((allResponces) => {
const sectionsData = allResponces.map((response, i) => ({
section: extendedSections[i],
firms: response,
}));
resolve(sectionsData);
})
.catch(reject);
});
};