Node.js 在javascript中如何将setTimeout与双回调一起使用
编辑:我在中用更简单的代码和更多的信息重写了这个问题。我将此保留为原样,以便人们可以根据自己的意愿参考详细的代码 我有一个Mongoose,带有子文档的节点设置。我需要调用一个函数,使用setTimeout根据某些条件更新一个数字。然而,有时由于回调没有快速返回,它会进入竞争状态。这里是一个示例方法Node.js 在javascript中如何将setTimeout与双回调一起使用,node.js,loops,callback,mongoose,Node.js,Loops,Callback,Mongoose,编辑:我在中用更简单的代码和更多的信息重写了这个问题。我将此保留为原样,以便人们可以根据自己的意愿参考详细的代码 我有一个Mongoose,带有子文档的节点设置。我需要调用一个函数,使用setTimeout根据某些条件更新一个数字。然而,有时由于回调没有快速返回,它会进入竞争状态。这里是一个示例方法 function myProcessPump(){ //Get top level documents based on some condition UserInfo
function myProcessPump(){
//Get top level documents based on some condition
UserInfo
.where('some_condition').lte(new Date())
.exec(function(err, UserInfoRetArray){
if (!err) {
if (UserInfoRetArray.length > 0){
//Iterate thru the top level documents
for (var i = 0; i < UserInfoRetArray.length; i++){
//Iterate thru sub-documents
for (var j = 0; j < UserInfoRetArray[i].someItems.length; j++){
// do some work...
do_work(UserInfoRetArray[i].someItems[j]);
//update status in db
set['someItems.$.some_condition'] = new Date((new Date()).getTime() + 10000) ;
UserInfo.update({_id: UserInfoRetArray[i]._id, "someItems._id":UserInfoRetArray[i].someItems[j]._id},
{$set: set}, function(err, numAffected) {
//set timeout so myProcessPump is called again.
setTimeout(myProcessPump, 1000);
});
}
}
} else {
//set timeout so myProcessPump is called again.
setTimeout(myProcessPump, 1000);
// I suspect this gets called when the previous call back does not
// complete in time causing the mulitple timers running in parallel.
}
} else {
//set timeout so myProcessPump is called again.
setTimeout(myProcessPump, 1000);
}
})
}
函数myProcessPump(){
//根据某些条件获取顶级文档
用户信息
.where('some_condition').lte(新日期())
.exec(函数(err,userinfortaray){
如果(!err){
如果(userinfortaray.length>0){
//遍历顶级文档
for(var i=0;i
我简化了代码来解释我想要什么。如何在不发生竞争条件的情况下成功调用setTimeout?未测试,但您可以尝试以下方法:
function myProcessPump() {
//Get top level documents based on some condition
UserInfo
.where('some_condition').lte(new Date())
.exec(function(err, UserInfoRetArray) {
//Wrap everything in an async function with a callback
var processUser = function(done) {
if (!err) {
if (UserInfoRetArray.length > 0) {
//Iterate thru the top level documents
for (var i = 0; i < UserInfoRetArray.length; i++) {
//Iterate thru sub-documents
for (var j = 0; j < UserInfoRetArray[i].someItems.length; j++) {
// do some work...
do_work(UserInfoRetArray[i].someItems[j]);
//update status in db
set['someItems.$.some_condition'] = new Date((new Date()).getTime() + 10000);
UserInfo.update({
_id: UserInfoRetArray[i]._id,
"someItems._id": UserInfoRetArray[i].someItems[j]._id
}, {
$set: set
}, function(err, numAffected) {
done();
});
}
}
} else {
done();
}
} else {
done();
}
}
//Call async function and when done redo the whole thing
processUser(function() {
//probably done need the timeout and can just call myProcessPump unless you really need a delay
myProcessPump();
//setTimeout(myProcessPump, 1000);
})
})
}
函数myProcessPump(){
//根据某些条件获取顶级文档
用户信息
.where('some_condition').lte(新日期())
.exec(函数(err,userinfortaray){
//用回调函数将所有内容包装在异步函数中
var processUser=函数(完成){
如果(!err){
如果(userinfortaray.length>0){
//遍历顶级文档
for(var i=0;i
您的问题仍然过于本地化。你需要试着找出问题的根源并询问它。明白了…我会相应地编辑。如果您可以用香草JS(更少的需求)编写这篇文章,这会有所帮助。当然,这并不总是可能的,我想在上面的代码中保留双循环和回调的风格。如果我改变它,那么它会显著地改变意图。但我还是会尝试的。我在中重写了这个问题