我有以下代码在async中运行对象:
async.each(Object.keys(shopList), function(key, callback){
var shop = shopList[key];
saveOrder(payId, shopList[key], key, req.body, req.user, function(err, newOrder){
if (err) {
callback(err);
}else{
orderCount++;
console.log("succes!", orderCount, newOrder.number);
callback();
}
})
}, function(err){
if (err) {
console.log("ERROR!", err);
}else{
console.log("done!");
}
})
在此函数中调用另一个函数。此代码如下所示:
saveOrder = function(payId, shop, nameSlug, body, user, callback){
console.log("saveOrder");
var orderNumber = 0;
Order.findOne().sort({_id:-1}).exec(function(err, latestOrder) {
if(latestOrder.number){
orderNumber = latestOrder.number.split("-")[1];
}
var order = new Order();
var date = new Date();
order.number = date.getFullYear().toString() + date.getMonth().toString() + "-" + (parseInt(orderNumber)+1);
order.date = date;
order.payId = payId;
order.status = {
status: "Created",
comment: "",
date: new Date()
};
order.comment = body.comment;
order.shop = {
name: shop.name,
nameSlug: nameSlug
}
order.billingDetails = {
//order details
}
order.sendDetails = {
//more order details
}
order.user = {
//yep, order details
}
var orderItems = [];
for(p = 0; p < shop.items.length; p++){
var product = shop.items[p];
var orderItem = {
_id: product._id,
name: product.name,
brand: product.brand[0].name,
price: product.price,
quantity: product.quantity
}
orderItems.push(orderItem);
}
order.items = orderItems;
order.save(function(err, result){
if (err){
console.log("err!", err);
return callback(err)
}else{
console.log("saved!");
return callback(null, result);
}
})
})
}
问题在于最后一个功能。在那里,我尝试创建一个必须唯一的订单号。我得到最后一个订单,拆分订单号并做+1。
当我的shopList中有更多对象时,此功能在未准备好时触发。换句话说,第一个订单当时没有保存,我会得到相同的订单号。
我该如何解决这个问题?我在async.each中尝试了一个setTimeout但是没有用。
答案 0 :(得分:1)
您可以使用locks使用互斥锁。
回调将等待互斥锁解锁以锁定它,使您无法同时执行。
var locks = require('locks');
var mutex = locks.createMutex();
saveOrder = function(payId, shop, nameSlug, body, user, callback){
mutex.lock(function () {
console.log("saveOrder");
var orderNumber = 0;
Order.findOne().sort({_id:-1}).exec(function(err, latestOrder) {
if(latestOrder.number){
orderNumber = latestOrder.number.split("-")[1];
}
var order = new Order();
var date = new Date();
order.number = date.getFullYear().toString() + date.getMonth().toString() + "-" + (parseInt(orderNumber)+1);
order.date = date;
order.payId = payId;
order.status = {
status: "Created",
comment: "",
date: new Date()
};
order.comment = body.comment;
order.shop = {
name: shop.name,
nameSlug: nameSlug
}
order.billingDetails = {
//order details
}
order.sendDetails = {
//more order details
}
order.user = {
//yep, order details
}
var orderItems = [];
for(p = 0; p < shop.items.length; p++){
var product = shop.items[p];
var orderItem = {
_id: product._id,
name: product.name,
brand: product.brand[0].name,
price: product.price,
quantity: product.quantity
}
orderItems.push(orderItem);
}
order.items = orderItems;
order.save(function(err, result){
if (err){
console.log("err!", err);
return callback(err)
}else{
console.log("saved!");
return callback(null, result);
}
})
})
mutex.unlock(); //don't forget to unlock the mutex
});
}
答案 1 :(得分:1)
您应该使用async.waterfall
代替async.each
,因为:
async.waterfall
- 运行函数的tasks数组,每个函数都将结果传递给数组中的下一个。 http://caolan.github.io/async/docs.html#waterfall
async.each
- 将函数iteratee并行应用于coll中的每个项目。
答案 2 :(得分:1)
修复了使用eachSeries()
代替each()