异步 Mongoose 调用
Posted
技术标签:
【中文标题】异步 Mongoose 调用【英文标题】:Asynchronous Mongoose Calls 【发布时间】:2017-06-21 04:54:05 【问题描述】:我有一个match
函数,可以将两个交换赌注配对或部分配对。起初我编写了一个简洁的函数,但它是同步的(使用 for 循环),现在我无法使用嵌套回调和 async
包将其转换为异步代码。到目前为止,我将粘贴到我的同步和异步函数下方。目前,我在异步代码中遇到错误,因为Cannot read property '_id' of undefined
但_id
是从存储在results
中的查询中提取的。
异步函数
match : function()
var results = Bet.find("paired" : false, _id:1, bet:1, market:1, odds:1, student:1, to_match:1, stake:1)
.sort(createdAt : 1);
async.forEach(results, function(doc, callback)
var result = doc[0];
var id = result._id;
var stake = result.stake;
var odds = result.odds;
var market = result.market;
var student = result.student;
var side = result.bet;
var to_match = result.to_match;
var opp_results = Bet.find("student":student, "market":market, "paired":false, "settled":false,
"bet": $ne : side, "_id" : $ne : id);
async.forEach(opp_results, function(opp_doc, callback2)
var temp_to_match = to_match;
var array = opp_doc[0];
var opp_id = array._id;
console.log("Comparing " + id + " with " + opp_id);
var opp_paired = array.paired;
var opp_to_match = array.to_match;
var opp_settled = array.settled;
if(temp_to_match <= opp_to_match)
temp_to_match -= opp_to_match;
opp_to_match -= temp_to_match;
if(temp_to_match <= 0)
paired = true;
if(opp_to_match <= 0)
opp_paired = true;
, callback);
, function(err)
console.log("done");
);
同步功能
sync_match : function()
Bet.find("paired" : false, _id:1, bet:1, market:1, odds:1, student:1, to_match:1, stake:1)
.sort(createdAt : 1)
.then(function(doc)
for(var j = 0; j < doc.length; j++)
var result = doc[j];
var id = result._id;
var stake = result.stake;
var odds = result.odds;
var market = result.market;
var student = result.student;
var side = result.bet;
var to_match = result.to_match;
Bet.find("student":student, "market":market, "paired":false, "settled":false,
"bet": $ne : side, "_id" : $ne : id).then(function(results)
for(var i = 0; i < results.length; i++)
var temp_to_match = to_match;
var array = results[i];
var opp_id = array._id;
console.log("Comparing " + id + " with " + opp_id);
var opp_paired = array.paired;
var opp_to_match = array.to_match;
var opp_settled = array.settled;
if(temp_to_match <= opp_to_match)
temp_to_match -= opp_to_match;
opp_to_match -= temp_to_match;
if(temp_to_match <= 0)
paired = true;
if(opp_to_match <= 0)
opp_paired = true;
console.log("we made it this far);
);
);
【问题讨论】:
Bet.find 是异步的,所以你不能像这样使用它var results = Bet.find(...)
最简单的方法是添加exec
-> Bet.find(...).sort(...).exec(function(err, results) async.forEach(results, ...));
【参考方案1】:
(更新:此解决方案有一个小错误。由于某种原因,当一个字段配对时,它应该停止,但它会继续配对和配对..)
根据 Molda 的建议,我设法获得了一个可行的异步解决方案:
match : function()
Bet.find("paired" : false, _id:1, bet:1, market:1, odds:1, student:1, to_match:1, stake:1)
.sort(createdAt : 1).exec(function(err, results)
async.forEach(results, function(doc, callback)
var id = doc._id;
var stake = doc.stake;
var odds = doc.odds;
var market = doc.market;
var student = doc.student;
var side = doc.bet;
var to_match = doc.to_match;
Bet.find("student":student, "market":market, "paired":false, "settled":false,
"bet": $ne : side, "_id" : $ne : id).exec(function(errs, res)
async.forEach(res, function(opp_doc, callback2)
var temp_to_match = to_match;
var opp_id = opp_doc._id;
var opp_student = opp_doc.student;
var opp_paired = opp_doc.paired;
var opp_to_match = opp_doc.to_match;
var opp_settled = opp_doc.settled;
if(temp_to_match <= opp_to_match)
var update_to_match = temp_to_match - opp_to_match;
var update_opp_to_match = opp_to_match - temp_to_match
if(update_to_match <= 0)
paired = true;
update_to_match = 0;
if(update_opp_to_match <= 0)
opp_paired = true;
update_opp_to_match = 0;
Bet.update("_id" : id,
$set : 'to_match': update_to_match,'paired' : paired
,new : true, multi: true).exec(function(err)
if(err)
throw err;
);
Bet.update("_id" : opp_id,
$set : 'to_match': update_opp_to_match, 'paired' : opp_paired
,new : true, multi:true).exec(function(err)
if(err)
throw err;
);
, function(err)
if(err)
throw err;
callback();
));
, function(err)
console.log("done");
));
【讨论】:
以上是关于异步 Mongoose 调用的主要内容,如果未能解决你的问题,请参考以下文章