如何为数组参数中的每个对象每次调用异步函数

时间:2013-11-24 08:22:44

标签: node.js asynchronous

我有一个异步功能,比方说 getConfigPricingFromResourceQuery(element,function(configPricingFromResourceQuery){

//做的事 });

我将elements []数组的每个值发送到这个异步函数。但是这个函数甚至被调用一次 - 尽管该数组包含多个值。更清楚的是,这个函数被称为单次将所有值一起发送到此函数。但这不是预期的,因为我需要为数组参数的每个值做一些事情。

完整代码如下:

功能定义:

function getConfigPricingFromResourceQuery(elements,callback){

            var configJson = {};

            // configJson contains parameters required for resourceservice validate api.
            var configJson = elements.parameters;

            trace.info(elements.uri);

            configJson.instanceTypeUri = elements.uri;

            jsonObject = JSON.stringify(configJson);

                // prepare the header
            var postheaders = {
            'Content-Type' : 'application/json',
            'Content-Length' : Buffer.byteLength(jsonObject, 'utf8')
            };

            // the post options
            var optionspost = {
            host :  '192.168.3.243',
            port :  5902,
            path :  '/apiv1.0/resourceQuery/validate',
            method : 'POST',
            headers : postheaders
            };

            // do the POST call to resource service
            var reqPost = http.get(optionspost, function(response) {
                trace.log("statusCode: ", response.statusCode);

                response.on('data', function(d) {
                    trace.info('POST result:\n');
                    process.stdout.write(d);
                    configPricing += d;
                    trace.info(configPricing);
                    trace.info('POST completed');
                    return callback(JSON.parse(configPricing));
                });
            }); 
            // write the json data
            reqPost.write(jsonObject);
            //reqPost.end();
            reqPost.on('error', function(e) {
                console.error(e);
            });

        //return callback(configPricing);
    };

调用此函数:

getConfigPricingFromResourceQuery(elements,function(configPricingFromResourceQuery){                 trace.info( '########################################');                 var metadataConfigJsonArray = [];                 var metadataConfigJson = {

                    chargeAmount: Math.round(configPricingFromResourceQuery.totalUnitPrice * 100)/100,
                    chargeamountUnit: configPricingFromResourceQuery.ChargeAmountUnit,
                    currencyCode: configPricingFromResourceQuery.CurrencyCode
                }
            metadataConfigJsonArray.push(metadataConfigJson);
            if(elements.metadata) { }
            else
            {
                elements.metadata={};
            }

            metadataModified = elements.metadata;

            // TODO : Remove this hard-coding
            elementlevelpricingSummary.Name = 'Hardware';

            if(configPricingFromResourceQuery.totalUnitPrice)
            {
                var chargeAmount = configPricingFromResourceQuery.totalUnitPrice;

                elementlevelpricingSummary.chargeAmount = Math.round(chargeAmount * 100)/100;
            }
            if(configPricingFromResourceQuery.ChargeAmountUnit)
            {
                var chargeAmountUnit = configPricingFromResourceQuery.ChargeAmountUnit;

                elementlevelpricingSummary.chargeAmountUnit = configPricingFromResourceQuery.ChargeAmountUnit;
            }
            if(configPricingFromResourceQuery.CurrencyCode)
            {
                var currencyCode = configPricingFromResourceQuery.CurrencyCode;

                elementlevelpricingSummary.currencyCode = configPricingFromResourceQuery.CurrencyCode;
            }   

            metadataModified.pricingSummary = metadataConfigJsonArray;

            configurableElementarray.push(elementlevelpricingSummary);

            // delete original metadata from workload json (to be replaced by metadata containing pricing summary)
            delete elementinfo.metadata;

            elementinfo.metadata = metadataModified;

            elementArray.push(elementinfo);

            // global workloadinfo variable is appended with array of elements with its pricing summary within metadata of respective elements
            workloadinfo.elements = elementArray;

            return callback(null, workloadinfo);
            });

1 个答案:

答案 0 :(得分:0)

它被调用一次因为你只调用它一次,传入整个数组:

getConfigPricingFromResourceQuery(elements, function(result){ 
    // Your lovely callback
})

如果你想获得elements数组中每个对象的配置价格,那么你必须为每个对象调用它

elements.forEach(function (e) {
    getConfigPricingFromResourceQuery(e, function (result) {
        // handle the result
    }
})

我还鼓励您使用节点样式回调function (err, value) {},它允许您通过回调传递错误。

如果你想将你的元素数组转换成一个结果数组,那么你需要更加聪明一点,你应该使用一个模块为你做这件事。在npm上查看并行数组模块,例如continuable-para

var para = require("continuable-para")

para(elements.map(function () {
    return getConfigPricingFromResourceQuery.bind(null, e)
}), function (err, pricesArray) {
    if (err) {
        return console.log(err)
    }

    pricesArray.forEach(function (price) { /* handle the price */ })
})