我的情况如下:
function smth(data) {
// save data to db.
Object.findOne({ _id: ceva['id']}, function(obj) {
obj.save();
});
}
从各种异步调用中调用此函数。存在竞争条件,其中第二个findOne调用在先前的save()运行之前运行。
有办法解决这个问题吗?也许使用异步库来串行运行?
答案 0 :(得分:1)
//make this follow async conventions with callback argument last
function smth(data, callback) {
//pseudocode database API here
db.save(data, function (error) {
if (error) {
callback(error);
return;
}
Object.findOne({ _id: ceva['id']}, function(obj) {
obj.save(callback);
});
});
}
这是基本的回调方法。如果您想稍微清理一下,可以使用async.js,或者学习callbackhell.com以了解更多避免嵌套函数的方法。
答案 1 :(得分:1)
您可以使用async控制流之一来确保smth()
的每次迭代按顺序发生。
如果您不赞成使用流控制库,则可以轻松实现每个事件的系列执行。请考虑以下代码段:
function smth(data, cb) {
// save data to db.
findOne({
id: data.id
}, function (err, obj) {
if (!err && obj) {
savedb(obj, cb);
} else {
cb(err);
}
});
}
function findOne(filter, cb) {
// simulate find
setTimeout(function () {
cb(null, {
id: filter.id,
name: 'test',
role: 'test'
});
}, 500);
}
function savedb(obj, cb) {
//simulate db save
setTimeout(function () {
cb(null, obj);
}, 500);
}
// iterations count
var count = parseInt(process.argv[2], 10) || 3;
(function iterate(i) {
console.log(i);
if (i === count) {
// iterations complete
process.exit(1);
}
var data = {
id: 123 + i
};
smth(data, function (err, res) {
console.log(err || res);
iterate(++i);
});
})(0);