从forEach回调中修改外部数组变量

时间:2015-11-19 16:16:41

标签: javascript arrays foreach scope

我遇到过类似的问题,但没有一个问题非常符合我的情况。

在下面的代码中,我使用dockerode Javascript库中的listContainers()函数列出我的Docker容器的ID。该片段改编自dockerode README上的片段。 listContainers调用正常工作,console.log行按预期输出id。问题是我无法将容器ID推送到函数调用之外声明的数组中 - 结果是在listContainers调用之后数组仍然为空。

我对Javascript不是很熟悉,但我认为这个问题是由于在回调函数中尝试推送。问题是listContainers是异步的,这意味着//CONSOLE LOG #2实际上在//CONSOLE LOG #1之前执行。

如何在函数调用之外的id数组中捕获id值?

//Here is where I want to store my container ids.
var ids = [];

//Here is the dockerode call
dockerCli.listContainers(function(err, containers) {

    containers.forEach(function(containerInfo) {

        //log shows the correct id
        console.log(containerInfo.Id);

        //Here I try to save the container id to my array
        ids.push(containerInfo.Id);
    });

    //CONSOLE LOG #1 Here I can see that the array has the correct values
    console.log("IDs: "+ids.toString());
});

//CONSOLE LOG #2 Shows that the array is empty
console.log("IDs: "+ids.toString());

2 个答案:

答案 0 :(得分:1)

在其他评论者的帮助下,我意识到listContainers调用是异步的,根本无法从中返回值。

那么如何初始化和使用我的ids数组?我创建了自己的函数来包装dockerode listContainers调用。然后,此函数将使用自己的回调来执行ids数组的工作。这允许我在我自己的回调中访问初始化的ids数组,将处理ids数组的功能与获取容器列表分开。

ids = [];

//Define my function that takes a callback function
//and just fetch the container ids
function getContainerJsonFromDocker(callback) {

    dockerCli.listContainers(function(err, containers) {

        containers.forEach(function(containerInfo) {
            console.log(containerInfo.Id);
            ids.push(containerInfo.Id);
        });
        return callback(ids);
    });
}

//Now call my function, and pass it an anonymous callback
//The callback does the processing of the ids array
getContainerJsonFromDocker(function(ids) {

    //This shows the array is initialised :)
    console.log("IDs: " + ids.toString());

    //Write my array to .json file
    var outputFilename = 'data.json';
    fs.writeFile(outputFilename, JSON.stringify(ids, null, 4),
            function(err) {
                if (err) {
                    console.log(err);
                } else {
                    console.log("JSON saved to " + outputFilename);
                }
            });
});

答案 1 :(得分:0)

你不需要传递全局变量id和回调试试这个,

//Here is where I want to store my container ids.
var ids = [];

//Here is the dockerode call
dockerCli.listContainers(function(err, containers) {

    containers.forEach(function(containerInfo) {

        //log shows the correct id
        console.log(containerInfo.Id);

        //Here I try to save the container id to my array
        ids.push(containerInfo.Id);
    });
});

//Shows that the array is empty
console.log("IDs: "+ids.toString());