需要有关节点js异步无限循环的帮助

时间:2015-04-28 12:41:30

标签: javascript node.js

我正在尝试这个http://justinklemm.com/node-js-async-tutorial/ 教程 我试过async.parallel(),我想一次又一次地循环一些函数。但它被困在第一个并且没有无限循环。任何人都可以就此提出建议吗?

编辑:代码:添加了2个应该一次又一次丢失的函数

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();
});
});
编辑:我正在尝试这个但不能循环。可能我在node.js中遗漏了一些基本问题。任何人都可以帮助我吗?

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

);

我无法循环。我想要的是在第1部分中我将执行函数,然后在第2部分我将遍历所有函数。我已尝试递归,可能不正确且无法执行

3 个答案:

答案 0 :(得分:2)

setTimeout用于在预定时间后调用一次。然而,这是使用称为递归的技术调用无限循环的最佳方法。例如:

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

    foo()
  }, 3000)  
}

请勿使用setInterval,因为它会再次调用,即使它尚未在函数中完成其他操作。

答案 1 :(得分:0)

您可能需要使用

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

setTimeout(),运行一次。

答案 2 :(得分:0)

您可以递归地执行此操作:

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

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

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

修改

你要编写的大多数函数都会有回调,因为Node.js是一种继续传递样式语言,而I / O是异步的。

node.js异步函数有一种模式,其中除了任意数量的参数之外的函数采用以下签名的额外函数:

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

因此函数声明应该类似于:

// 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"]);
};

如果您在下面的代码执行之前明确地return得到并且错误。例如:

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使用该模式。它是一个很棒的控制流库,但你需要了解如何控制延续流程。

在你的函数中SensorTag.discover必须将回调作为第二个参数,以便在完成该函数后继续继续。 此外,如果您想将它们直接插入async,那么所有其他功能都应该具有相同的签名。

如果您的所有功能(未发布)都具有该签名并且您正确处理错误SensorTag.discover可能如下所示:

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

如果这三个函数看起来像上面的getCurrentUser示例应该有效。您遇到的问题可能在于这些内部功能。

Whilst是相同的,但它只需要3个函数,其中重要的是中间的那个,那是应该遵循callback(err)模式的函数。所以:

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

我不知道SensorTag.discover做了什么,但它看起来像是在其他地方定义并采用了一个函数(?)。我猜它应该看起来像这样(允许继续):

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

我建议你在深入异步库之前阅读有关Node.js和异步编程模式的内容。正如我之前所说, async 非常强大,但您需要了解这些概念,否则您将永远进行调试。