2

I was trying with this http://justinklemm.com/node-js-async-tutorial/ tutorial I tried async.parallel() and I wanted to loop through some function again and again. But It was stuck onto first and didn't loop infinitely. Can anyone please suggest me regarding this?

EDIT : code : added 2 functions that should be lopped again and again

var util = require('util');
var async = require('async');
var SensorTag = require('./index');
var USE_READ = true;

SensorTag.discover(function(sensorTag) {
    console.log('discovered: ' + sensorTag);

var items = [9000];
var asyncTasks = [];

items.forEach(function(item){
  // We don't actually execute the async action here
  // We add a function containing it to an array of "tasks"
    asyncTasks.push(function(callback){
        console.log('connectAndSetUp');
        sensorTag.connectAndSetUp(callback);
    }),

    asyncTasks.push(function(callback){
        console.log('readDeviceName');
        sensorTag.readDeviceName(function(error, deviceName) {
            console.log('\tdevice name = ' + deviceName);
            callback();
        });
    });
});

asyncTasks.push(function(callback){
  // Set a timeout for 3 seconds
    setTimeout(function(){
    // It's been 3 seconds, alert via callback
    callback();
    }, 3000);
});

//async.parallel(asyncTasks, function(){
//console.log('DONE');

async.parallel(asyncTasks, function(){
  // All tasks are done now
  //doSomethingOnceAllAreDone();
});
});

EDIT : I am trying with this one but not able to loop. Probably I am missing some fundamental issue here in node.js. Can anyone help me out?

var util = require('util');
var async = require('async');
var SensorTag = require('./index');
var USE_READ = true;

var count = 0;

/*PART 1*/  


SensorTag.discover(function(sensorTag) {
    console.log('discovered: ' + sensorTag);

  async.series([
      function(callback) {
        console.log('connectAndSetUp');
        sensorTag.connectAndSetUp(callback);
      },
      function(callback) {
        console.log('readDeviceName');
        sensorTag.readDeviceName(function(error, deviceName) {
          console.log('\tdevice name = ' + deviceName);
          callback();
        });
      },
      function(callback) {
        console.log('readSystemId');
        sensorTag.readSystemId(function(error, systemId) {
          console.log('\tsystem id = ' + systemId);
          callback();
        });
      }

  ]);

});

/*PART 2*/

async.whilst(
      function () { return count < 5; },
      function (callback) {

      function(callback) {
        console.log('enableIrTemperature');
        sensorTag.enableIrTemperature();
      },
      function(callback) {
        setTimeout(callback, 2000);
      },
      function(callback) {
        console.log('readIrTemperature');
        sensorTag.readIrTemperature(function(error, objectTemperature, ambientTemperature) {
            console.log('\tobject temperature = %d °C', objectTemperature.toFixed(1));
            console.log('\tambient temperature = %d °C', ambientTemperature.toFixed(1));

            callback();
          });

      },
      function (err) {
        console.log('5 seconds have passed');
        // 5 seconds have passed
      }
          count++;
          setTimeout(callback, 1000);
      }

);

I can not loop through this. What I wanted is in the PART 1 I would execute the functions and then at the PART 2 I would loop through all function. I have tried recursive , may be not properly and unable to execute

5
  • Please show your code. Without that, it's very difficult to guess what you did wrong. Commented Apr 28, 2015 at 12:43
  • added code @germi > I added 1 function,later on will add more.just was checking Commented Apr 28, 2015 at 12:47
  • @germi what I wanted is looping through functions again and again Commented Apr 28, 2015 at 12:48
  • @germi Have you seen my edit? I had added code Commented Apr 28, 2015 at 15:02
  • There are more tools than just the ones listed in that tutorial, specifically there is whilst Commented Apr 28, 2015 at 19:20

3 Answers 3

2

setTimeout is used for calling something once after a predetermined time. It is, however the best way to call an infinite loop using a technique called recursion. Example:

var foo = function() {
  setTimeout(function() {
    // do stuff that may take time

    foo()
  }, 3000)  
}

Don't use setInterval as it will call again, even if it hasn't completed other actions in the function.

Sign up to request clarification or add additional context in comments.

2 Comments

But there is no loop, the function is not calling again
What happened is it stuck on the last function called and not starting executing again. It hangs on last function
0

may you need to use

setInterval(function(){
    callback();
}, 3000)

setTimeout(), run once.

Comments

0

You can do it recursively:

asyncTasks.push(function (callback){
  var count = 0;

  myTask(function fn(err) {
    if(err || count >= 5) return callback(err);
    count++;
    myTask(fn);
  });
});

or

asyncTasks.push(function task(callback){
    if(err || taskCount >= 5) return callback(err);
   // assuming taskCount is in the outer scope
    taskCount++; 
    task(callback);
});

Edit

Most of the functions you'll be writing will have a callback since Node.js is a continuation-passing style language and I/O is asynchronous.

There's a pattern for node.js asynchronous functions where functions apart from any number of params take an extra function with the following signature:

// results is optional
function(err,[results]){}

So a function declaration should look something like:

// next() here is the function described above
SensorTag.registerEvent = function(event,next) {
  // Do stuff...
  // Do more stuf...

  if(stuffFailed){
    // If first param is truthy
    // something went wrong
    return next("Some error")
  } 

  // null as first param mean
  // implicitly that everything went ok
  next(null,["some","result"]);
};

If you get and error you explicitly return before the code below gets executed. Eg:

var getCurrentUser = function(callback){
  DB.findCurrentUser({ foo: 'always' },function(err,user) {
    if(err){
      return callback(err);
    }

    return callback(null,user);
  });
}

getCurrentUser(function(err,userProfile) {
  if(err){
    console.log(err);
    return;
  }

  console.log('OK! We got user: %s',userProfile.id);
});

Async uses that pattern. It's a great library for control flow but you need to understand how to control the continuation flow.

In your function SensorTag.discover MUST take a callback as a second parameter to allow the continuation to keep going once you are done with that function. Also, all your other functions should have that same signature if you wanna plug them directly into async.

If all your functions (not posted) have that signature and you are handling errors correctly SensorTag.discover may look something like this:

// This function needs a callback if you wish
// to continue your program
SensorTag.discover(function(sensorTag) {
  console.log('discovered: ' + sensorTag);

  async.series([
    sensorTag.connectAndSetUp,
    sensorTag.readDeviceName,
    sensorTag.readSystemId
  ],function(err,tasksData) {
    if(err){
      console.error(err);
      return;
    }
    console.log('All tasks succedded!');
    // No external callback to continue
  });
});

If those three functions look like the getCurrentUser example from above that should work. The problem you are having may be in those internal functions.

Whilst is the same but it only takes 3 functions where the one that matters is the one in the middle and that's the one that should follow the callback(err) pattern. So:

SensorTag.discover(function(sensorTag) {
  console.log('discovered: ' + sensorTag);

  var count = 0;

  async.whilst(
    function () { return count < 5; },
    function (callback) {
      console.log('count === %d',count);
      async.series([
        sensorTag.connectAndSetUp,
        sensorTag.readDeviceName,
        sensorTag.readSystemId
      ],callback);
    },
    function (err) {
      // This is our continuation callback
      // But again, we don't have an external callback
    }
  );
});

I don't know what SensorTag.discover does but it looks like it's defined elsewhere and takes a function (?). I'm guessing it should look something like this maybe (to allow for continuation):

SensorTag.discover = function(sensorTag,next) {
  console.log('discovered: ' + sensorTag);

  var count = 0;

  async.whilst(
    function () { return count < 5; },
    function (callback) {
      console.log('count === %d',count);
      async.series([
        sensorTag.connectAndSetUp,
        sensorTag.readDeviceName,
        sensorTag.readSystemId
      ],callback);
    },
    function (err) {
      next(err);
    }
  );
});

// Then you call it externally
SensorTag.discover(mySensorTag,function(err) {
  if(err){
    console.error(err);
  }

  // Do more stuff...
});

I would suggest you read about Node.js and asynchronous programming patterns before diving deep into the async library. As I said before, async is very powerful but you need to understand those concepts or you'll be debugging forever.

1 Comment

Maroshi can you please see my edits? I tried looping but not happening. Look at my second edit please

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.