Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How could I run a function after the completion of a for loop in Node.js?

Say if I have a structure in Node.js shown below:

for (i = 0; i < 50; i++) {
    //Doing a for loop.
}

function after_forloop() {
    //Doing a function.
}

after_forloop();

So how could I make sure the after_forloop() function is fired after the forloop is completed?

In case if you want to see what I am actually working on:

var http = require('http');
http.createServer(function (req, res) {
    res.writeHead(200, {'Content-Type': 'text/plain'});
    res.end('Hello World\n');
}).listen(1337, '127.0.0.1');
console.log('Server running at http://127.0.0.1:1337/');

var proxyChecker = require('proxy-checker');
var fs = require('fs');

function get_line(filename, line_no, callback) {
    fs.readFile(filename, function (err, data) {
        if (err) throw err;
        var lines = data.toString('utf-8').split("\n");
        var firstLineBreak = data.toString('utf-8').indexOf("\n");
        var originalText = data.toString('utf-8');
        var newText = originalText.substr(firstLineBreak + 1);
        if(+line_no > lines.length){
            return callback('File end reached without finding line', null);
        }

        callback(null, lines[+line_no], newText);
    });
}


for (i = 0; i < 50; i++) {
    get_line('proxy_full.txt', i, function(err, line, newText){
        fs.appendFile('proxy.txt', line + '\n', function (err) {
            if (err) throw err;         
        });     
        fs.writeFile('proxy_full.txt', newText, function (err) {
            if (err) throw err;
        });
    })
}

after_forloop();

function after_forloop() {
    proxyChecker.checkProxiesFromFile(
        // The path to the file containing proxies
        'proxy.txt',
        {
            // the complete URL to check the proxy
            url: 'http://google.com',   
            // an optional regex to check for the presence of some text on the page
            regex: /.*/
        },
        // Callback function to be called after the check
        function(host, port, ok, statusCode, err) {
            if (ok) {
                console.log(host + ':' + port);
                fs.appendFile('WorkingProxy.txt', host + ':' + port + '\n', function (err) {
                    if (err) throw err;             
                });
            }                   
        }
    );

    setTimeout(function(){
        fs.writeFile('proxy.txt', "", function (err) {
            if (err) throw err;
        });
        console.log('Proxy Check Completed.')
        process.exit(1); 
    }, 5000);
}

Basically I like to allow the node server run 50 test on a list proxy servers at a time (within five seconds). And then the server should save the working proxies to a new file.

like image 813
Aero Wang Avatar asked Jan 13 '15 02:01

Aero Wang


People also ask

How do you break out of a loop in node?

TL;DR: use break to exit a loop in JavaScript.

How do I make JavaScript function infinitely?

Another way to do this is by simply referencing itself in a timeout, like this: function sayHello(){ console. log('Hello World! '); setTimeout(sayHello, 1000); }; sayHello();

Can we use for loop in node JS?

Node. js ships with the for…of and for…in loops. These two loops provide a convenient iteration besides the common for loop. Both loops give you a clean syntax for iterations and quick access to keys or values.


5 Answers

If there is no magic happening then it should be straight forword.

Function:-

function after_forloop() {
    //Doing a function.
}

For Loop:-

for (i = 0; i < 50; i++) {
    //Doing a for loop.
}
for (i = 0; i < 50; i++) {
    //Doing another for loop.
}
after_forloop();

This will call after_forloop just after both for loops finishes. Because for loop is a blocking call, calling of after_forloop() has to wait.

Note:- If you are doing some async task in for loops then the function will be called after loop finished, but the work you are doing in loops might not finished by the time of calling function.

like image 66
Mritunjay Avatar answered Nov 02 '22 14:11

Mritunjay


Maybe this helps:

var operationsCompleted = 0;
function operation() {
    ++operationsCompleted;
    if (operationsCompleted === 100) after_forloop(); 
}
for (var i = 0; i < 50; i++) {
    get_line('proxy_full.txt', i, function(err, line, newText){
        fs.appendFile('proxy.txt', line + '\n', function (err) {
            if (err) throw err;
            operation();
        });     
        fs.writeFile('proxy_full.txt', newText, function (err) {
            if (err) throw err;
            operation();
        });
    })
}

Admittedly this isn't an elegant solution. If you're doing a whole lot of this you might want to check out something like Async.js.

like image 24
Ethan Lynn Avatar answered Nov 02 '22 16:11

Ethan Lynn


If you're doing any async operation in the for loop, you can simply keep it like

function after_forloop() {
// task you want to do after for loop finishes it's execution
}


 for (i = 0; i < 50; i++) {
 //Doing a for loop.

 if(i == 49) {
  after_forloop() // call the related function
 }
}

Still in node.js, instead of making use of for loops with asynchronous functions, you should see the async module. Here's Async.js or you can consider using recursion too.

like image 33
Parth Vyas Avatar answered Nov 02 '22 14:11

Parth Vyas


use the Async module, Its easy and best.

async.each(array, function (element, callback) {
                        callback()
                    }, async function (err) {
                       console.log("array ends")
                    });
like image 38
Amit Rana Avatar answered Nov 02 '22 14:11

Amit Rana


You can handle the last iteration of the for loop with a conditional checking index.

for(let i = 0; i < 10; i++){
  if(i == 10 - 1){
    your_function();
  }
}
like image 4
Smit Luvani Avatar answered Nov 02 '22 14:11

Smit Luvani