简体   繁体   English

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

[英]Modifying external array variable from within forEach callback

I have come across similar questions, but none that quite fits my scenario. 我遇到了类似的问题,但没有一个完全适合我的情况。

In the code below, I am using the listContainers() function from the dockerode Javascript library, to list the ids of my Docker containers. 在下面的代码中,我正在使用dockerode Javascript库中的listContainers()函数列出我的Docker容器的ID。 The snippet is adapted from one on the dockerode README. 该代码段是从dockerode README上的一个代码改编而成的。 The listContainers call works and the console.log line outputs the ids as expected. listContainers调用成功,console.log行按预期输出ID。 The problem is that I cannot push the container IDs into the array declared outside the function call - the result is that the array is still empty after the listContainers call. 问题是我无法将容器ID推入在函数调用外部声明的数组中-结果是在listContainers调用之后该数组仍然为空。

I am not very experienced with Javascript, but I think this problem is due to attempting the push inside the callback function. 我对Javascript不太熟悉,但是我认为此问题是由于尝试在回调函数内部进行推送而引起的。 The problem is that the listContainers is asynchronous, so this means that //CONSOLE LOG #2 actually executes before //CONSOLE LOG #1 . 问题在于listContainers是异步的,因此这意味着//CONSOLE LOG #2实际上在//CONSOLE LOG #1之前执行。

How can I capture the id values into the ids array outside the function call? 如何在函数调用之外将id值捕获到ids数组中?

//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());

With the help of other commenters, I realised that the listContainers call is asynchronous and there is simply no way to return a value from it. 在其他评论者的帮助下,我意识到listContainers调用是异步的,根本无法从中返回值。

So how to initialise and work with my ids array? 那么如何初始化和使用我的ids数组呢? I created my own function that wraps the dockerode listContainers call. 我创建了包装dockerode listContainers调用的函数。 This function then takes its own callback to do the work with the ids array. 然后,此函数将使用自己的回调函数来处理ids数组。 This allowed me to access the initialised ids array in my own callback, separating the functionality of processing the ids array from fetching the container list. 这使我可以在自己的回调中访问初始化的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);
                }
            });
});

you dont need to pass the global variable ids along with callback try this, 您无需将全局变量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());

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM