javascript - Javascript/NodeJS:在 forEach 内完成 .find 之前的 html 渲染
问题描述
这个循环应该检查数据库中与从 salesforce api 结果中提取的 opps 匹配的 opps,然后创建一个新的 opp 或找到现有的 opp 并将其推送到数组。似乎 res.render 在找到 opp 之前正在运行。它创建了一个新的 opp,但在页面呈现时数组返回空。
Account.find({owner:req.user._id, prospect:'false'}).sort({ammount:'desc'}).populate({path: "notes", options:{ sort:{ 'date': -1 } } }).exec(function(err, allAccounts) {
let callGoal = req.user.callGoal;
if(err){
res.send(err);
}else{
// if auth has not been set, redirect to index
if (!req.session.accessToken || !req.session.instanceUrl) { res.redirect('/'); }
//SOQL query
let q = "SELECT Id,Amount,CloseDate,LastActivityDate,Name,StageName,account.Name FROM Opportunity WHERE CloseDate < 2018-10-01 AND OwnerId = '0050a00000J12PdAAJ' AND IsClosed = false AND StageName != 'Stage 6: Won'";
//instantiate connection
let conn = new jsforce.Connection({
oauth2 : {oauth2},
accessToken: req.session.accessToken,
instanceUrl: req.session.instanceUrl
});
//set records array
let softopps = [];
let sfOpps = [];
let query = conn.query(q)
.on("record", function(record) {
sfOpps.push(record);
})
.on("end", function() {
console.log("total in database : " + query.totalSize);
console.log("total fetched : " + query.totalFetched);
let user = req.user;
sfOpps.forEach(function(sfopp){
if(err){
res.send(err);
}else{
Opp.findOne({sfid:sfopp.Id}).exec(function(err, opp){
if(!opp.length){
Opp.create(req.body, function(err, newOpp) {
if(err){
res.send(err)
}else{
newOpp.sfid = sfopp.Id;
newOpp.name = sfopp.Name;
newOpp.owner = user.sfid;
newOpp.save();
return softopps.push(newOpp)
}
})
}else{
return softopps.push(opp);
}
})
}
})
res.render("myaccounts", {accounts:allAccounts, callGoal:callGoal, user:user, sfOpps:sfOpps, opps:softopps});
})
.on("error", function(err) {
console.error(err);
})
.run({ autoFetch : true, maxFetch : 4000 });
}
});
解决方案
你的Opp.findOne()
和Opp.create()
调用是异步的,所以它们在res.render()
.
另一方面,你几乎用所有不必要的请求杀死了你的 mongodb。
试试这个逻辑(从 开始.forEach
)
Opp
通过 id查找所有ssfOpps
- 找出哪些
Opp
s 没有找到并创建它们 - 连接所有找到的和未找到
Opp
的 - 然后,然后才回应
我没有测试该代码,但它可以大致让您了解我的意思
Opp.find({ sfid : { $in: sfOpps.map(opp => opp.id) } })
.then(found => {
const foundIds = found.map(opp => opp.sfid)
const notFound = sfOpps.filter(opp => !foundIds.includes(opp.sfid)).map(sfopp => {
return {
sfid: sfopp.sfid,
name: sfopp.name,
owner: user.sfid
}
})
Opp.insertMany(notFound)
.then((insertResult) => {
res.render("myaccounts", {
accounts: allAccounts,
callGoal: callGoal,
user: user,
sfOpps: found.concat(notFound),
opps: softopps
});
}).catch(handleError)
}).catch(handleError)
推荐阅读
- mysql - 计算多个字段,包括空字段
- linux - 通过 & 命令在后台运行的服务和进程之间的区别
- javascript - JavaScript 获取请求网站并运行 document.querySelector
- postgresql - 在 Postgresql db 上使用 ALTER SEQUENCE 进行 Sqitch 迁移没有效果
- spring-boot - Swagger 在发布请求中找不到没有 @RequestBody 的模型
- android - 从 GoogleFit API 获取空值 - 心率聚合
- mysql - Kubernestes 中的作业出错(如何使用 Kubernetes 部署 Rails 应用程序?)
- elasticsearch - 如何在 ElasticSearch 中使用具有 _score 值的范围函数?
- core-data - 通过关系忽略没有相关实体的实体,形成具有标题标题的核心数据实体列表
- powershell - 如何在excel中为每个单独的单元格获取一个?