NodeJS setTimeout/setInterval callback as a string - node.js

as far as I know, NodeJS does not support callbacks passed by strings in setTimeout/setInterval functions. (e.g setTimeout("myfunc()", 100);)
Is there any implementation or any other solution to make this work? (e.g instead of calling callback, just eval it, etc..)
I'm just trying to load raw webpage which does exactly same thing so NodeJS just throws exceptions on that.

One way I can suggest is:
setTimeout(function(){
eval("myfunc()")
}, 100);
Edit (to handle evalString passed as an argument)
function callMe(evalString){
return function(){eval(evalString);}
}
setTimeout(callMe('myFunc()'), 100);

Just replace native setTimeout with your one:
setTimeout = timeoutWrapper(setTimeout);
function timeoutWrapper(origSetTimeout) {
var win = typeof global !== 'undefined' ? global : window;
function _setTimeout(fn) {
var code;
if(typeof fn === 'string') {
code = fn
fn = function wrapEval() {
eval(code);
};
}
arguments[0] = fn;
origSetTimeout.apply(win, arguments);
}
return _setTimeout;
}
Test it:
setTimeout('console.log(123)', 100);
setTimeout(function(a,b,c) {
console.log(a, b, c);
}, 100, 'aaa', 'bbb', 'ccc');

Related

Timeout change args without re setTimeout

const timer = setTimeout(({a, b}) => {
console.log(a + b)
}, 3000, {a:1, b:2});
setTimeout(() => {
Object.assign(timer._timerArgs,[{a:2, b:2}])
}, 1000)
// Output: 4
Please have a look at this. What I'm going to do is, going to change the timer args if needed before it's called.
I don't want to use clearTimeout and setTimeout again for this process.
But not sure this is the right way. And plus how can I set the priority per each timer in case the timeout will be the same.
I don't know where you got ._timerArgs from. I've never seen that. Without dipping into undocumented properties (that are only present in node.js), you can do it like this:
const objA = {a:1, b:2};
const timer = setTimeout(({a, b}) => {
console.log(a + b);
}, 500, objA);
objA.a = 2;
objA.b = 3;
This will output 5 which reflects that you changed the property values before the timer callback fired.
Since objects in Javascript are passed by pointer (not copied), you can still modify the object that objA points at any time before the timer fires and see the effect inside the timer callback.
But, then you don't even have to pass the arguments into the setTimeout(). You can just reference a parent scoped variable in the callback:
const objA = {a:1, b:2};
const timer = setTimeout(() => {
console.log(objA.a + objA.b);
}, 500);
objA.a = 2;
objA.b = 3;
This will also output 5.
If you want arbitrary argument modification (not properties embedded in an object), and you want it to be only using supported, standard tools that work in all implementations of Javascript, then you can't do that with just setTimeout(). You could make your own timer wrapper though:
class MyTimer {
constructor(fn, t, ...args) {
this.args = args;
this.fired = false;
this.timer = setTimeout(() => {
this.fired = true;
fn.apply(null, this.args);
}, t);
}
cancel() {
clearTimeout(this.timer);
}
hasFired() {
return this.fired;
}
}
const timer = new MyTimer((...args) => {
console.log("timer callback arguments:", args);
}, 500, "hello", "goodbye");
timer.args = ["ola", "adios", "amor", "amigo"];
You can then modify the array in the .args property at any time before the timer fires and they will be passed to the timer callback.

How do you find out the caller function which is in different file?

//foo.js
module.exports.foo = function foo() {
//
}
// Bar.js
var f = require(./foo);
function bar() {
f.foo(); // How to find out the caller function is `foo` ?
}
How do you find out the caller function which is in different file in JavaScript?
I've seen a similar answer in this question.
But I got this logging :
debug: caller is function wrapper() {
var fn = (this && this !== root && this instanceof wrapper) ? Ctor : func;
return fn.apply(thisArg, arguments);
}
I am writing a global function to log the error from the module it is calling, so here I am trying to find out the caller function.
If you do really need to do that, I'd probably do it via Error's stack:
function log() {
var stack = new Error().stack;
// ...log the stack
}
If you like, you can do some post-processing on the stack string, but I would tend to avoid it as the exact format can evolve from dot release to dot release of V8 (I can tell from your code you're using NodeJS).
Example (requires a browser that supports Error#stack, like Chrome [which uses the same JavaScript engine as NodeJS] or Firefox):
function log() {
console.log(new Error().stack);
}
function foo() {
log();
}
function bar() {
foo();
}
bar();

Can Node.js stream be made as coroutine?

Is there a way to make Node.js stream as coroutine.
Example
a Fibonacci numbers stream.
fibonacci.on('data', cb);
//The callback (cb) is like
function cb(data)
{
//something done with data here ...
}
Expectation
function* fibonacciGenerator()
{
fibonacci.on('data', cb);
//Don't know what has to be done further...
};
var fibGen = fibonacciGenerator();
fibGen.next().value(cb);
fibGen.next().value(cb);
fibGen.next().value(cb);
.
.
.
Take desired numbers from the generator. Here Fibonacci number series is just an example, in reality the stream could be of anything a file, mongodb query result, etc.
Maybe something like this
Make the 'stream.on' function as a generator.
Place yield inside the callback function.
Obtain generator object.
Call next and take the next value in stream.
Is it at-least possible if yes how and if not why? Maybe a dumb question :)
If you don't want to use a transpiler (e.g. Babel) or wait until async/await make it to Node.js, you can implement it yourself using generators and promises.
The downside is that your code must live inside a generator.
First, you can make a helper that receives a stream and returns a function that, when called, returns a promise for the next "event" of the stream (e.g. data).
function streamToPromises(stream) {
return function() {
if (stream.isPaused()) {
stream.resume();
}
return new Promise(function(resolve) {
stream.once('data', function() {
resolve.apply(stream, arguments);
stream.pause();
});
});
}
}
It pauses the stream when you're not using it, and resumes it when you ask it the next value.
Next, you have a helper that receives a generator as an argument, and every time it yields a promise, it resolves it and passes its result back to the generator.
function run(fn) {
var gen = fn();
var promise = gen.next().value;
var tick = function() {
promise.then(function() {
promise = gen.next.apply(gen, arguments).value;
}).catch(function(err) {
// TODO: Handle error.
}).then(function() {
tick();
});
}
tick();
}
Finally, you would do your own logic inside a generator, and run it with the run helper, like this:
run(function*() {
var nextFib = streamToPromises(fibonacci);
var n;
n = yield nextFib();
console.log(n);
n = yield nextFib();
console.log(n);
});
Your own generator will yield promises, pausing its execution and passing the control to the run function.
The run function will resolve the promise and pass its value back to your own generator.
That's the gist of it. You'd need to modify streamToPromises to check for other events as well (e.g. end or error).
class FibonacciGeneratorReader extends Readable {
_isDone = false;
_fibCount = null;
_gen = function *() {
let prev = 0, curr = 1, count = 1;
while (this._fibCount === -1 || count++ < this._fibCount) {
yield curr;
[prev, curr] = [curr, prev + curr];
}
return curr;
}.bind(this)();
constructor(fibCount) {
super({
objectMode: true,
read: size => {
if (this._isDone) {
this.push(null);
} else {
let fib = this._gen.next();
this._isDone = fib.done;
this.push(fib.value.toString() + '\n');
}
}
});
this._fibCount = fibCount || -1;
}
}
new FibonacciGeneratorReader(10).pipe(process.stdout);
Output should be:
1
1
2
3
5
8
13
21
34
55

Knockout Declarations

I am new for knockout. I would like to know the differences between these three and which one is best as per latest framework.
Approach 1 (InvoiceTypes): Declaring all variables and methods using comma and finally using return statement to expose public interface methods.
Approach 2 (OrderTypes): It is similar to Approach 1 but used semicolon to differentiate each variable or method.
Apprach 3 (ModelTypes): It is similar to Approach 2 but with out return statement.
Finally specified calling way of start method in each approach in jquery read.
Approach 1
window.Domain = window.Domain || {}
window.Domain.InvoiceTypes = function () {
var types = ko.observableArray(),
getTypes = function() { return types; },
start = function() {
types.push({name:"knockout"});
},
submit = function() {
alert("submit");
};
return {
getTypes: getTypes,
start: start,
submit: submit
};
}();
Approach 2
window.Domain.OrderTypes = function () {
var types = ko.observableArray();
var getTypes = function() { return types; };
var start = function() {
types.push({name:"knockout"});
};
var submit = function() {
alert("submit");
};
return {
getTypes: getTypes,
start: start,
submit: submit
};
}();
Approach 3
window.Domain.ModelTypes = function () {
var self = this;
self.types = ko.observableArray();
self.getTypes = function() { return types; };
self.start = function() {
types.push({name:"knockout"});
};
self.submit = function() {
alert("submit");
};
};
<script type="text/javascript">
$(document).ready(function() {
window.Domain.InvoiceTypes.start();
window.Domain.OrderTypes.start();
var obj = new window.Domain.ModelTypes();
obj.start();
});
</script>
The difference I can see clearly is, single var declaration & return statement and using of self by this keyword.
Please provides your inputs.
Approaches #1 and #2 are akin to static factory methods. Rather than creating an object with the new keyword, you are calling a static "factory" function that creates and returns a new type for you. As for the comma versus semicolon approach, both are valid, but I prefer semicolons over commas. Why? Because javascript is more forgiving with semicolons than with commas. You can omit a semicolon here and there and the script will still run, whereas commas must always be present for the javascript to be correctly parsed. It is also easier to read with semicolons when your script gets larger.
Approach #3 is what most knockout developers do, or should to. Firstly, because you don't need the little () at the end of your function declaration, so it looks more like a class. However, it looks like you have an error in there:
self.start = function() {
//types.push({name:"knockout"}); // types was not declared,
self.types.push({name:"knockout"}); // only self.types was declared
};
... same error here
self.getTypes = function() {
//return types; types was never declared
return self.types;
};

Does node.js support yield?

Is there any way to get generators into node.js?
I'm currently faking them with callbacks, but I have to remember to check the response of the callback inside of my generator function which creates a lot of if (callback(arg) === false) return;
I want something like in python:
for p in primes():
if p > 100: break
do_something(p)
which I'm doing in node like this:
primes(function(p) {
if (p > 100) return false;
do_something(p)
});
Maybe something like coffeescript could help?
Yes, since version 0.11. Enjoy!
http://wingolog.org/archives/2013/05/08/generators-in-v8
http://jlongster.com/A-Study-on-Solving-Callbacks-with-JavaScript-Generators
The answer is "not currently" but Marcel seems to be my hero. Lets hope this goes somewhere:
https://groups.google.com/forum/#!msg/nodejs/BNs3OsDYsYw/oCsWBw9AWC0J
https://github.com/laverdet/node-fibers
You can use generators in Node.js, but only in 0.11+. Node.js 0.12 (stable) is now available. Add --harmony_generators or --harmony to the command line parameters of node to enable it.
With Traceur, you can compile advanced JavaScript to vanilla JavaScript. You could make a loader for node.js that does this on-the-fly. Since it runs on, and compiles to vanilla JavaScript, it runs in node.js < 0.11 as well as in the browser.
Facebook has developed a lighter version that only supports generators, called Regenerator. It works similarly to Traceur.
Apparently not in the current stable version. You can however achieve the same using node-fibers + promises.
Here is my implementation:
var fiber = require('fibers');
module.exports.yield = function (promise) {
var currentFiber = fiber.current;
promise
.then(function (value) {
currentFiber.run(value);
})
.otherwise(function (reason) {
currentFiber.throwInto(reason);
});
return fiber.yield();
};
module.exports.spawn = function (makeGenerator) {
fiber(function () {
makeGenerator.apply(this, Array.prototype.slice.call(arguments, 1));
}).run();
};
And a sample code on how it works: (query.find returns a promise)
var generators = require('./utils/generators');
var query = require('./utils/query');
generators.spawn(function () {
try {
var field1 = generators.yield(query.find('user', { _id : '1' }));
var field2 = generators.yield(query.find('user', { _id : '2' }));
console.log('success', field1[0]._id, field2[0]._id);
}
catch (e) {
console.error('error', e);
}
});
You might check out wu.js at http://fitzgen.github.com/wu.js/ It has lots of interesting iterator functions.
Yes and no.
var myGen = (function () {
var i = 0;
return function () {
i++; return i; }
})();
var i;
while ((i = myGen()) < 100 ) {
do something; }
As you see, you can implement something like one using closures, but it does not have native generators.
The issue proposing generatiors in v8 has recently been accepted by v8 project member.
Please vote there to make yield come true.
Update 2014: Node does support callbacks now. The following is a post from 2010.
You should use callbacks. If the function does something asynchronously, you may also want a continuation callback (continuation is a bad word, since it also means something else, but you get my point.)
primes(function(p) {
if (p > 100) return false // i assume this stops the yielding
do_something(p)
return true // it's also better to be consistent
}, function(err) { // fire when the yield callback returns false
if (err) throw err // error from whatever asynch thing you did
// continue...
})
Updated with example code
I flipped it, so that it returns true on complete (since null, false and undefined all evaluate to false anyways).
function primes(callback) {
var n = 1, a = true;
search: while (a) {
n += 1;
for (var i = 2; i <= Math.sqrt(n); i += 1)
if (n % i == 0)
continue search;
if (callback(n)) return
}
}
primes(function(p) {
console.log(p)
if (p > 100) return true
})
We are using gnode for generators in node < 0.11.3 - https://github.com/TooTallNate/gnode
Yes Node.js and JavaScript now have both synchronous iterators (as of atleast Node v6) and asynchronous iterators (as of Node v10):
An example generator/iterator with synchronous output:
// semi-pythonic like range
function* range(begin=0, end, step=1) {
if(typeof end === "undefined") {
end = begin;
begin = 0;
}
for(let i = begin; i < end; i += step) {
yield i;
}
}
for(const number of range(1,30)) {
console.log(number);
}
A similar async generator/iterator.
const timeout = (ms=1000) => new Promise((resolve, reject) => setTimeout(resolve, ms));
async function* countSeconds(begin=0, end, step=1) {
if(typeof end === "undefined") {
end = begin;
begin = 0;
}
for(let i = begin; i < end; i += step) {
yield i;
await timeout(1000);
}
}
(async () => {
for await (const second of countSeconds(10)) {
console.log(second);
}
})();
There is a lot to explore here are some good links. I will probably update this answer with more information later:
Generators
Generator functions
Iterable Protocol
Iterator Protocol
Async Generators
Jake Archibald's Article on Async Generators
Async Iterators
for await ... of

Resources