我正在尝试这个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部分我将遍历所有函数。我已尝试递归,可能不正确且无法执行
答案 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 非常强大,但您需要了解这些概念,否则您将永远进行调试。