Homebridge trigger function in other function
I want to trigger a binded function such as getCurrentFanSpeed in setInterval
I have tried .getCurrentFanSpeed or .getCurrentFanSpeed.call();
setInterval(function () {
fanservice.getCurrentFanSpeed ;
fanservice.log("Interval: Get Current Fan Speed");
}, this.interval);
Actually it doesn't run the code.
only displayed Interval: Get Current Fan Speed every 10sec
If Fanservice accepts callback function, You can get a result like below.
setInterval(async function () {
fanservice.getCurrentFanSpeed(function(result) => {
console.log(result);
});
fanservice.log("Interval: Get Current Fan Speed");
}, this.interval);
It might help you
Finally i found that i can just use emit() to call the function
such as
fanService.getCharacteristic(Characteristic.RotationSpeed).emit("set");
thanks for all.
Related
As I understand, the differences between process.nextTick() and setImmediate() are the followings:
callbacks scheduled by process.nextTick() will ALL be executed before entering the next event loop, while callbacks scheduled by setImmediate() will only be executed ONE per event loop.
Base on the characteristics stated above, it can be said that: recursive call of process.nextTick() can cause the program to hang up, while recursive call of setImmediate() will not.
Then I've written some testing code to verify the statements above, here is my code:
process.nextTick(function() {
console.log('nextTick1');
});
process.nextTick(function() {
console.log('nextTick2');
});
setImmediate(function() {
console.log('setImmediate1');
process.nextTick(function() {
console.log('nextTick3');
});
});
setImmediate(function() {
console.log('setImmediate2');
});
My expected result should be
nextTick1, nextTick2, setImmediate1, nextTick3, setImmediate2
, but what I actually got is
nextTick1, nextTick2, setImmediate1, setImmedate2, nextTick3
Then I've run another test to study the behavior of setImmediate():
//the following code is using express as the framework
app.get('/test', function (req, res) {
res.end('The server is responding.');
});
app.get('/nexttick', function (req, res) {
function callback() {
process.nextTick(callback);
}
callback();
res.end('nextTick');
});
app.get('/setimmediate', function (req, res) {
function callback() {
setImmediate(callback);
}
callback();
res.end('setImmediate');
});
Step1: I accessed http://localhost:3000/nexttick on my browser and I got the text nexttick.
Step2: I accessed http://localhost:3000/test to test if my server is still responding to requests, and I didn't get any response, the browser kept waiting for response. This is nothing surprising because the recursive call of process.nextTick() had hanged up the server.
Step3: I restarted my server.
Step4: I accessed http://localhost:3000/setimmediate and got the text setimmediate
Step5: I accessed http://localhost:3000/test again to test if my server is still responding. And the result is as the same as Step2, I didn't get any response and the browser kept waiting for response.
This means the behavior of process.nextTick() and setImmediate() is pretty much the same but as I know they are not.
I was wondering why is this happening or have I misunderstood sth. Thank you.
P.S. I am running Node v0.12.7 under Windows 10.
Actually your test results looks ok (I only refer to the first test).
Your comments "setImmediate() will only be executed ONE per event loop." is wrong, See https://nodejs.org/api/timers.html#timers_setimmediate_callback_arg
and thats the reason you don't understand the first test results.
Basically process.nextTick will put your function at the end of the current event loop while setImmediate will put it at the next event loop.
But executing multiple setImmediate is ok and they will all go to that same next event loop.
In
setImmediate(function() {
console.log('setImmediate1');
process.nextTick(function() {
console.log('nextTick3');
});
});
setImmediate(function() {
console.log('setImmediate2');
});
Basically you have put 2 function sthat will be invoked in next event loop, and in one of them you put another nextTick which will be invoked at the end of that same cycle but at the end of that same cycle.
So it will first invoke those 2 setImmediate and than the nextTick that was called in the first.
I was reading this article on howtonode,
but don't get why it's fake async ?
So fake async is described as:
function asyncFake(data, callback) {
if(data === 'foo') callback(true);
else callback(false);
}
asyncFake('bar', function(result) {
// this callback is actually called synchronously!
});
Correct code: always async
function asyncReal(data, callback) {
process.nextTick(function() {
callback(data === 'foo');
});
}
My question is what's wrong with the first part of code ?
Why nextTick() can promise the 'right' effect ?...
Please explain to me. Thanks.
Nothing's wrong with the first case. However, it's just that you have to be proactive (as the developer) to know exactly what's happening in your code.
In the first case, you are not doing any I/O, and the callback is not actually being put into the Event Loop. It just the same as doing this:
if(data === 'foo')
return true;
else
return false;
However, in second case, you are putting the callback into the event loop until the next iteration.
In terms of how things work, nothing's wrong. However, you need to be aware of what implications are.
For instance:
function maybeSync(a, cb) {
if(a === 'a') {
cb('maybeSync called');
} else {
// put the called into event-loop for the next iteration
process.nextTick(function() {
cb('maybeSync called');
});
}
}
function definitelySync() {
console.log('definitelySync called');
}
someAsync('a', function(out) {
console.log(out);
});
definitelySync();
In the top case, which one gets called first?
If the input is "a" then the output is:
maybeSync called
definitelySync called
If the input is something else (e.g. not "a") then the output would be:
definitelySync called
maybeSync called
You need to make them consistent, as it would be easy to distinguish if the callback can be called sync/async based on the condition. Again comes back to being responsible, being consistent and being aware of what's happening in your code. =)
In the async fake function - you can see that callback is called as a normal function invocation i.e in the same call stack.
someone calls async fake fn
async fake fn calls the callback passed to it
If that callback takes time to complete - the async fake fn is kept waiting i.e it remains in call stack.
By using process tick - we are just submitting the callback function to be scheduled for execution.
This process tick call completes immediately and the asyncreal will return immediately. Thus the callback will be executed in asynchronous way.
I'm new to node.js.
I have tried to create a setTimeout that executes a database SELECT Query and repeats 3 seconds after processing the SELECT results has completed.
var newDBMessagesInterval = 3000; // 3 Seconds
(function newDBMessagesSchedule() {
setTimeout(function() {
dbNewMessagesQuery(function(dbResults,dbResultsLength) {
console.log(dbResults);
newDBMessagesSchedule();
});
}, newDBMessagesInterval)
})();
function dbNewMessagesQuery(callback) {
dbConnection.query("SELECT data1,data2,data3 FROM table WHERE condition=1;", function (dbError, dbResults, dbFields) {
if(dbResults.length > 0) {
callback(dbResults,dbResults.length);
}
});
callback();
}
It appears the setTimeout number of loops increases each time it runs (eg: first one console.log(dbResults), but then 2times and then 4 etc). Also I'm not sure if its waiting on the database SELECT to completed before trying to process the next time.
Looking for some advise on how to create this loop correctly with node.js
thx
Your dbNewMessagesQuery calls callback twice. Once synchronously, and once after the db query succeeds. You should just be calling it once after the query is done. With your current code, for every call to newDBMessagesSchedule, you queue up two more calls to run later.
function dbNewMessagesQuery(callback) {
dbConnection.query("SELECT data1,data2,data3 FROM table WHERE condition=1;", function (dbError, dbResults, dbFields) {
callback(dbResults, dbResults.length);
});
}
I'd also recommend not bothering to pass the length separately, and instead pass along the error if there is one. Currently you just assume there will never be an error.
function dbNewMessagesQuery(callback) {
dbConnection.query("SELECT data1,data2,data3 FROM table WHERE condition=1;", function (dbError, dbResults, dbFields) {
callback(dbError, dbResults);
});
}
I've been using the Q module to implement promises on a project I'm working on.
I'm using the static method Q.fncall() to create a promise out of a node.js style function (based on callbacks returning err,result).
The problem is that I need to stop the execution of said function after a certain amount of time, so I used the function "timeout" of the Q module. So, after x amount of time, the "error" callback on the done function executes and let's me handle the timeout but the function itself keeps getting executed until it reaches its final callback even if the handler is not listening anymore.
The question is: Is there any way to stop the execution of a function after the timeout is executed? I know I can just set a variable on the timeout handler and keep checking in the function if the timeout is over, but I'm hoping for a cleaner way of achieving this.
The code is as follows:
Q.nfcall(test1, id)
.timeout(1000)
.done(
function (value) {
console.log("SUCCESS: " + value);
},
function (reason) {
console.log("ERROR " + reason);
},
function (progress) {
console.log("PROGRESS " + progress);
}
);
And the test1 function:
function test1(id,callback){
db_rw_pool.query("SELECT * FROM table WHERE id=?",[id], function(err,result) {
if(err){
callback(err,null);
}
else {
setTimeout(function(){
console.log("I DON'T WANT YOU TO BRE PRINTED")
callback(null,result);
},2000);
}
return;
});
}
In my ideal situation, the code inside setTimeout(...,2000) should never be executed. Is this possible?
Thanks in advance.
I think you're concerning yourself over a too low level. Once you've ran test1, there's no way to stop db_rw_pool.query from executing, and its callback from being called (unless you'd take special precautions in this db_rw_pool.query method). The results for the SQL query WILL come back. The question is whether the code will swallow these results at some point, or not. The swallowing in this case happens in the code for Q's timeout method. Just place any code you don't want to be executed in the onFulfilled handler of done.
You write
The problem is that I need to stop the execution of said function after a certain amount of time, so I used the function "timeout" of the Q module.
The timeout method won't stop this function from executing. Rather, it returns a new promise that is instructed to fail if the promise it's bound to (the one which you've made with Q.nfcall) is not fulfilled within the set period (1000 ms in this case).
If you somehow want to stop a callback from executing, you could wrap it inside a function that checks for the time. Something like:
function stopExecutingAfter(timeout, fn) {
var stopifAfter = Date.now() + timeout
return function() {
if(Date.now() > stopIfAfter) return
fn.apply(null, arguments)
}
}
Q mainly concerns itself with promises, so it's obvious that it won't do this for you.
Using this technique, you could make a nfcallWithTimeout function that returns a promise while protecting the passed function (by wrapping it in something like the above) as well. Then you don't have to configure the timeout behavior twice.
Consider using another language because there is no way to do this in Javascript.
Greeting all,
I want to call a function repeatedly, but wanted each call to run only when the previous call is completed. Does the Async's whilst fit what I need? Or do the calls happen in parallel?
Thanks!
Gary
Whilst will do what you need, it runs each function in series. Before each run it will do the "test" function to make sure it should run again.
Their example:
var count = 0;
async.whilst(
function () { return count < 5; },
function (callback) {
count++;
setTimeout(callback, 1000);
},
function (err) {
// 5 seconds have passed
}
);
As Chad noted, Async's whilst will do the job.
You may want to consider Async's until (inverse of whilst). Both do the same job however the key difference is:
async.whilst will call the function each time the test passes
async.until will call the function each time the test fails
Async's whilst should do the trick for you. Please note the version of async you will be using before referring to the code on the accepted answers. As one of the comments in the accepted answer suggests, the structure of this loop has slightly changed which might not be very easy to spot.
Async v2: Accepted Answer
Async v3: https://caolan.github.io/async/v3/docs.html#whilst
Their Example:
var count = 0;
async.whilst(
function test(cb) { cb(null, count < 5); },
function iter(callback) {
count++;
setTimeout(function() {
callback(null, count);
}, 1000);
},
function (err, n) {
// 5 seconds have passed, n = 5
}
);