2017-02-21 55 views
0

我有以下代碼通過一個對象與異步運行:異步每個運行速度?

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,但這不起作用。

回答

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 
    }); 
} 
+0

嗯的,添加的代碼的建議,但仍是同樣的效果,觸發功能,他完成之前執行他的代碼... – NVO

+0

爲什麼在分配「latestOrder.number.split(」 - 「)[1];」「後沒有使用」ordernumber「 –

+0

固定使用eachSeries而不是每個,但我會繼續使用mutex.lock函數。 – NVO

1

您應該使用async.waterfall代替async.each,因爲:

async.waterfall - 運行的功能任務數組中的系列,每個路過的結果數組中的下一個。 http://caolan.github.io/async/docs.html#waterfall

async.each - 將函數iteratee並行應用於coll中的每個項目。

+0

感謝您的回覆。隨着你的評論我進一步看,我發現函數eachSeries,它具有相同的功能,1功能。所以,我現在用另一個答案中的mutex.lock來使用它! – NVO