我正在处理mongoDb(https://jira.mongodb.org/browse/SERVER-1243)的限制,这迫使我运行update()
次N次,直到我最终得到“0”作为总更新记录(太棒了呃? )。
所以,我必须转过身来:
_mongoUglyUpdateWrapper: function( querySelector, updateObject, options, cb ){
var self = this;
var total = 0;
self.collection.update( querySelector, updateObject, options, function( err, partialTotal ){
if( err ) return cb( err );
cb( null, partialTotal );
});
},
重复调用self.collection.update直到partialTotal
最终为0的东西 - 此时它最终可以调用回调。我通常使用异步,但这里非常不同。
它需要递归,但我不确定解决此问题的最佳,最简单方法是什么。帮助
(偏离主题:是的,就性能而言,这可能是一场灾难,但这就是当你信任年轻技术时所得到的;我写的下一层是MySql)。
答案 0 :(得分:1)
我能想到的最好的方法是命名函数并检查函数内部:
_mongoUglyUpdateWrapper: function( querySelector, updateObject, options, cb ){
var self = this;
var total = 0;
function checkIfZero( err, partialTotal ) {
if( err ) return cb( err );
if( partialTotal !== 0 ) return self.collection.update( querySelector, updateObject, options, checkIfZero );
cb( null, partialTotal );
}
self.collection.update( querySelector, updateObject, options, checkIfZero );
},
答案 1 :(得分:1)
您可以使用async.doWhilst
(或类似的async.doUntil
,我觉得这更自然)。将更新记录的数量存储在函数外部的变量中,以便真值测试可以访问它。使用doWhilst
代替whilst
,以确保该功能运行一次。如果计数在运行后仍然为零,则表示您已完成(async
负责处理)。
答案 2 :(得分:0)
答案版本#1,感谢Qantas 94 Heavy,使用checkIfZero
:
_mongoUglyUpdateWrapper: function( querySelector, updateObject, options, cb ){
var self = this;
var total = 0;
var rnd = Math.floor(Math.random()*100 );
function checkIfZero( err, partialTotal ) {
if( err ) return cb( err );
total += partialTotal;
if( partialTotal !== 0 ){
return self.collection.update( querySelector, updateObject, options, checkIfZero );
}
cb( null, total );
}
self.collection.update( querySelector, updateObject, options, checkIfZero );
},
版本#2,使用async.shilst可能在堆栈上更加温和。(感谢Henry Merriam)
_mongoUglyUpdateWrapper: function( querySelector, updateObject, options, cb ){
var self = this;
var total = 0;
var partialTotal;
async.whilst(
function() { return partialTotal != 0 },
function( callback ){
self.collection.update( querySelector, updateObject, options, function( err, t ){
if( err ) return callback( err );
total += t;
partialTotal = t;
callback( null );
});
},
function (err) {
if( err ) return cb( err );
cb( null, total );
}
);
},