async每个都跑得快?

时间:2017-02-21 14:58:17

标签: node.js asynchronous async.js

我有以下代码在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但是没有用。

3 个答案:

答案 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()

的问题

http://caolan.github.io/async/docs.html#eachSeries