for循环后调用代码完成node.js

时间:2017-08-12 12:59:34

标签: node.js object asynchronous synchronization

我的Node.js项目有问题。 我试图返回"报告" for循环结束后的对象。 我的代码(更新):

            var apigClient = apigClientFactory.default.newClient({
            accessKey: '*******',
            secretKey: '*******',
            invokeUrl: '*******'
        });

        var pathTemplate = '*******';
        var method = 'POST';
        ///loop - calling API
        for (var i = 0; i < Object.keys(jsonOutput).length; i++)
        {
            var body = {
                        *******: *******,
                        *******: *******
                    };
            apigClient.invokeApi({}, pathTemplate, method, {}, body)
            .then(function (result) {
                Report.numberOfSuccess++;
                console.log(JSON.stringify(result.data));
            }).catch(function (result) {
                Report.numberOfFailed++;
                Report.reportList.push([jsonOutput[i].id,jsonOutput[i].currency]);
            });

        }
        /////finally
        console.log(Report);

我的输出:

{ reportList: [], numberOfSuccess: 0, numberOfFailed: 0 }
{ reportList: [], numberOfSuccess: 0, numberOfFailed: 0 }
{ reportList: [], numberOfSuccess: 0, numberOfFailed: 0 }
{"status":500,"error":"Internal Server Error"}
{"status":500,"error":"Internal Server Error"}
{"status":500,"error":"Internal Server Error"}
{"status":500,"error":"Internal Server Error"}
{"status":500,"error":"Internal Server Error"}
{"status":500,"error":"Internal Server Error"}
{"status":500,"error":"Internal Server Error"}
{"status":500,"error":"Internal Server Error"}
{"status":500,"error":"Internal Server Error"}

如您所见,报告对象尚未就绪。

我需要的是:

{"status":500,"error":"Internal Server Error"}
{"status":500,"error":"Internal Server Error"}
{"status":500,"error":"Internal Server Error"}
{"status":500,"error":"Internal Server Error"}
{"status":500,"error":"Internal Server Error"}
{"status":500,"error":"Internal Server Error"}
{"status":500,"error":"Internal Server Error"}
{"status":500,"error":"Internal Server Error"}
{"status":500,"error":"Internal Server Error"}
{ reportList: [], numberOfSuccess: 4, numberOfFailed: 0 }
{ reportList: [], numberOfSuccess: 3, numberOfFailed: 0 }
{ reportList: [], numberOfSuccess: 2, numberOfFailed: 0 }

我试图使用承诺和回调,但它不起作用。

1 个答案:

答案 0 :(得分:0)

问题是你在for循环中执行异步代码,它继续以同步方式执行。一旦事件循环处理其内部FIFO queue回调,异步调用就会完成。

如上所述,您可以使用promises来处理此问题,但调用者函数必须能够处理承诺。

如果您不想处理promises,另一种方法是使用async模块来处理您正在处理的项目数组。您可以查看eachLimit函数,它可以帮助您解决此问题。

var asyncFunc = function() {
    return new Promise(function(resolve, reject) {
        resolve('asyncFunc called...');
    });
};

for (var i = 0; i < 10; i++) {
    asyncFunc()
    .then(function(result) {
        console.log('Result from asyncFunc is: ' + result);
    })
    .catch(function(error) {
        console.error(error);
    });

    console.log('Value of i is : ' + i);
}

基于上面的解释,上面的例子将在每次调用asyncFunc之前为i的每次迭代输出for loop的值。

var async = require('async');

var asyncFunc = function() {
    return new Promise(function(resolve, reject) {
        resolve('asyncFunc called...');
    });
};

var mainFunc = function(done) {
    var items = [1, 2, 3, 4, 5, 6, 7, 8, 9];

    async.eachLimit(items, 1, function(item, callback) {
        asyncFunc()
        .then(function(result) {
            console.log('Result for item ' + item + ' is: ' + result);
            callback();
        })
        .catch(function(error) {
            callback(error);
        });
    }, function(error) {
        if (error) {
            console.error(error);

            done(error);
        } else {
            console.log('Done processing items...');

            done();
        }
    });
};

mainFunc(function(error) {
    if (error) {
        console.log(error);
    } else {
        console.log('Processing completed...');
    }
});

在这里,使用async库,您可以控制数组中每个项目的处理方式。您的调用函数(即mainFunc)可以传递将在async.eachLimit完成时调用的回调。

在这种情况下,我建议您更多地了解synchronousasynchronous操作。

更新

以下是仅使用promises的简单示例。

var asyncFunc = function(item) {
    return new Promise(function(resolve, reject) {
        console.log(item);
        resolve('asyncFunc called...');
    });
};

var mainFunc = function() {
    var items = [1, 2, 3, 4, 5, 6, 7, 8, 9];

    var promises = items.map(asyncFunc);

    return Promise.all(promises);
};

mainFunc()
.then(function(result) {
    console.log(result);
})
.catch(function(error) {
    console.error(error);
});
  

Promise.all()方法返回一个在什么时候解析的Promise   可迭代参数中的所有promise都已解决或者何时解析   iterable参数不包含任何承诺。它拒绝理由   拒绝的第一个承诺。