Aero Wang
Aero Wang

Reputation: 9217

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.

Upvotes: 12

Views: 51649

Answers (7)

L.Gaunt
L.Gaunt

Reputation: 89

I had this problem and created a function using setTimeout to repeatedly check every half second whether the for loop was completed before calling the function to run after the for loop completed:

function forLoopFunction() {
    // any other function code
    for loop {
      // body of for loop
    }
    checkForLoopComplete();
}
function checkForLoopComplete() {
  if (condition which indicates for loop is complete) {
    // call function to run on for loop complete
    functionOnForLoopComplete();
  } else {
    setTimeout(checkForLoopComplete, 500);
  }
}

function functionOnForLoopComplete() {
    // function code
}

Upvotes: 0

Rohit Nishad
Rohit Nishad

Reputation: 2755

Simplest one!

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

Upvotes: 1

Smit Luvani
Smit Luvani

Reputation: 53

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

Upvotes: 4

Amit Rana
Amit Rana

Reputation: 43

use the Async module, Its easy and best.

async.each(array, function (element, callback) {
                        callback()
                    }, async function (err) {
                       console.log("array ends")
                    });

Upvotes: 2

Parth Vyas
Parth Vyas

Reputation: 507

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.

Upvotes: 10

Ethan Lynn
Ethan Lynn

Reputation: 1009

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.

Upvotes: 10

Mritunjay
Mritunjay

Reputation: 25882

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.

Upvotes: 8

Related Questions