异步函数内的forEach循环-Javascript

时间:2018-07-10 23:32:48

标签: node.js asynchronous

我是Node JS的新手,我正努力了解如何在异步函数内运行for循环。 for循环中还有另一个异步函数。

我应该在promArray中得到一些值的响应。但是,我得到的是一个空数组。

const rp = require('request-promise');

const options2 = {
    uri: 'uri',
    method: 'GET',
    auth: {
        'user': 'username',
        'pass': 'password'
    }
};
var promArray = [];


function executeMethod() {

    rp(options2).then(function(body) {

        const jsonData = JSON.parse(body).result;
        // iterate through the pods

        jsonData.forEach(element => {
            promArray.push(getProjectName(element.u_hig_proj_name.value))
        });


    });

    return Promise.all(promArray);
}

function getProjectName(projectSysId) {
    const projectTableAttrbutes = {
        uri: 'uri',
        method: 'GET',
        auth: {
            'user': 'username',
            'pass': 'password'
        }
    };
    return new Promise(function(res, rej) {
        // call the project table
        rp(projectTableAttrbutes).then(function(body) {
            //console.log(JSON.parse(body).result.name);
            res(JSON.parse(body).result.name);
        })
    })
}


// final execution 

executeMethod().then(function(done) {

    console.log(done);

});

2 个答案:

答案 0 :(得分:1)

这里的问题是您的forEachthen块内。这意味着它将异步执行。

然而,您的return语句位于then之外,因此将在承诺已解决且then块运行之前立即执行。那就是为什么它是空的。

这可能是解决方案:

function executeMethod() {
    return rp(options2).then(function(body) {

        const jsonData = JSON.parse(body).result;
        // iterate through the pods

        jsonData.forEach(element => {
            promArray.push(getProjectName(element.u_hig_proj_name.value))
        });

        return Promise.all(promArray);

    });
}

在此解决方案中,两个诺言被链接并连续执行。首先,返回外部承诺(return rp(...))。在其then块中,返回第二个承诺(return Promise.all(...))。这将是最终值,executeMethod将用来解析。

I highly recommend checking out this article了解有关诺言链接的更多信息,因为它是处理诺言时的关键工具。

答案 1 :(得分:0)

当您第一次调用executeMethod()时,您的promArray为空,因此数组中的所有promise(即全部为零)都得到了解析,因此promise会立即解析。我猜您实际上感兴趣的诺言是jsonData.forEach调用中生成的诺言,因为您将这些诺言添加到了promArray中。因此,我建议您实际上说jsonData.map,然后按承诺返回每个getProjectName调用,然后将整个.map调用包装在Promise.all中:

return Promise.all(
    jsonData.map(
        element => getProjectName(element.u_hig_proj_name.value)
    )
);

然后您可以像其他诺言一样使用它。


而且,我不太了解您在getProjectName函数中的工作-为什么围绕请求创建一个新的Promise包装器?已经是一个诺言了。