losing global variable value - javascript

This is for a gameing application
I declare the variable skipnpc which is designed as an indicator that a non player character has used his turn and any AI code related to his behavior is skipped for a period of time. the problem I have is I am loosing the value of skipnpc somehow I indicated where in the console.log commands I issue is related to varaible scope but I don't understand how to fix it.
function npcMovement() {
skipnpc = false;...
sql4 = "SELECT id FROM game_moblist WHERE spawn_id =" + spawnid + " AND posx=" + parseInt(mobpathx[mobpathx.length - 1]) + " AND posy=" + parseInt(mobpathy[mobpathy.length - 1])
connection.query(sql4, function (err, send, fields) {
console.log("skipnpc pathing")
io.sockets.emit('groupmoveresult', send, parseInt(mobpathx[mobpathx.length - 1]), parseInt(mobpathy[mobpathy.length - 1]))
skipnpc = true
console.log("skipnpc=true:" + skipnpc)
});
console.log("skipnpc = false:" + skipnpc)
Later I use
if (skipnpc==false){
...
before any further AI code is attempted

connection.query is executed asynchronous. Thus you get to your final line here before it is done.

To put it real simply, skipnpc is guaranteed to still be false by the time you hit your last console.log(...). You're not giving your connection.query(...) any time to execute before trying to look at its result. Anything that relies on the result of connection.query(...) has to be executed as part of the callback you passed to it; otherwise none of the results will have come in when you try to access them.
Asynchronous programming takes some getting used to. You might be able to reorganize your code using the async module and using its waterfall(...) method so everything doesn't wind up deeply nested. But you've got to realize that if you make an asynchronous call, your code will flow right past it.

Related

How to insert parentheses in an eval statement to order operations in JavaScript?

This is the Code Sandbox: https://codesandbox.io/s/rw0j2orqmp
The file this is in is reducers.js
I'm building a React/Redux calculator app, and currently I'm in the process of making the output display the results of the current calculation held in state. It works without parentheses but calculates the whole formula rather than a piece at a time. To fix this I wanted to wrap each piece in parentheses to have it calculate separately, taking off the method and then sticking it back on when the first part is finished calculating by doing this:
value:
methods.indexOf(state.lastValue) < 0
? eval("(" + state.calc.slice(0, -1) + ")" + state.calc.slice(-1) + state.value)
: state.value,
but when I have it like that, I get "Unexpected token ) " .
Is there an easier way to accomplish what I'm trying to do, and or is there a functional replacement for eval() in this case?
I'm not sure why you're using eval or parentheses here. Is there a reason why this won't work for you?:
methods.indexOf(state.lastValue) < 0
? state.calc.slice(0, -1) + state.calc.slice(-1) + state.value
: state.value
If you need to group things together, just use parentheses without the eval.
methods.indexOf(state.lastValue) < 0
? ((state.calc.slice(0, -1)) + state.calc.slice(-1) + state.value)
: state.value
Update: I see what you're saying, sorry, it was hard to understand from your original explanation and I was on my mobile and couldn't really inspect your sandbox.
I'm thinking it may be better to keep a string that you can evaluate simply later, for example, if you have "7 + 3" stored and press *, turn wrap that original string in parentheses and add the *, resulting in "(7 + 3) *", etc. Then whenever you want to show the result, you just evaluate that single stored calculation.
If you insist on doing eval that way, I'll just tell you that it works. For example, try this in the console:
eval("(" + "7 + 3" + ")" + "* 2")
// 20
So you may be doing something wrong with the values you are returning from the slice, which results in an eval error.
Try console logging that whole expression to see what's actually going on.

Callbacks, exports and javascript [duplicate]

This question already has answers here:
How do I return the response from an asynchronous call?
(41 answers)
Closed 5 years ago.
I don't like to ask a question but I feel I need to know how, or a better way of doing this. I should say first that I'm new to Javascript having done Java before and am new to callbacks as well. I read some other questions, but am still having some difficulty. This is truly horrible.
In rounds.js I have this
exports.getCurrentRound = function(callback) {
exec(header + token + address, function (error, stdout, stderr) {
sys.print('stdout: ' + stdout);
rounds = stdout;
if (error !== null)
callback(null, err);
else
callback(null, currentRound);
});
}
In index.js I have this.
var result;
rounds.getCurrentRound( function (err, cr) {
currentRound = cr;
console.log("the current round is" + currentRound);
});
How can i get result to equal something? Hope that makes sense. Keep in mind i'm running windows. And am reluctant to use promises. Whatever that is. I hope I'm not wasting your time too much.
Thanks.
Alternatively if there's a way to just run this synchronously please tell me what it is. I just want to know the proper way of doing this.
You're nearly there! You've defined result at the top but you now just need to set it.
var result; // default: undefined
rounds.getCurrentRound( function (err, cr) {
currentRound = cr;
console.log("the current round is" + currentRound);
result = currentRound;
});
// result will be set at some point in the future
The problem is that you don't know when result will be set. You can find out by constantly checking if it's set using setTimeout, but even that is asynchronous!
The answer is you need to treat your whole program asynchronously. Whoever needs result will have to pass in a callback.
Promises are just a way to say 'I want the value of this variable whenever it is set'.
var result = new Promise(function(resolve, reject){
rounds.getCurrentRound( function (err, cr) {
currentRound = cr;
console.log("the current round is" + currentRound);
resolve(currentRound); // set the actual value of result
});
});
// you can use the value of result later like this:
result.then(function(resultValue){
console.log('The result is ' + resultValue);
});
But notice that even then, to use the value of result you still need to pass a callback. It's still asynchronous! But the benefit you gain is that you can pass the result promise around your code and other bits of code can use the resolved promise to perform something once the value is set. For instance, let's say you want to use the value of result in two places in your code...
result.then(function(resultValue){
console.log('My code is using result ' + resultValue);
});
// somewhere else
result.then(function(resultValue){
console.log('This other code is also using result ' + resultValue);
});
If you're using the callback method that you first started out with (in your question), both cases where you need to use the value of result need to be inside the callback. But using promises, we've managed to separate them out.
In short, the answer is that you have to think about your code slightly differently, instead of thinking about it as a series of steps, try thinking about it as a series of events that might happen in sequence but might also happen 'whenever they're done' - asynchronously.

Get a return value from arbitrary eval'd code

I have a requirement that the user can provide arbitrary statements which can be stored in a function and called later to get a return value. A simple example of this is that userInput might be
var x = 10;
x;
I would store this via
var callback = function() {
return eval(userInput);
}
and then running callback() returns 10 as expected.
However, I also need to support the case with an explicit return statement, ie userInput might be
var x = 10;
return x;
In this case the eval method above will fail with SyntaxError: return not in function. Instead I could store callback as
var callback = new Function(userInput);
My issue is that I would like to combine these two approaches according the rule 'get explicit return value otherwise get the result of the last executed statement'. In particular this can't be done with analysis of the code at callback creation time as the user could potentially do something odd like
if(envVar < 10)
return a;
b * 0.5;
which combines both.
Any thoughts on how to structure the creation of the callback function to accommodate these possible inputs? Unfortunately it is not possible to enforce one style or the other on the user.
UPDATE to answer some of the comments below.
One solution suggested is to search for a return token and choose between new Function and eval. This doesn't work for my last example, see http://jsfiddle.net/ZGb6z/2/ - out4 should be "no" but ends up being undefined as the last executed statement is not returned.
Another suggestion is to modify the user input to add an explicit return on the last line if one is not found. Unfortunately it's not possible to know which statement will be executed last. Consider
var x = 10;
switch(x) {
case 10:
100;
break;
default:
200;
break;
}
When called it should return 100, but it would take some serious analysis to determine where to put returns for arbitrary code.
Just use a try catch, manipulating the input will be very painful for you, and try catch can't really make your code any more obtuse at this point.
var failback = function () {
try {
return eval(userInput);
} catch (e) {
return Function(userInput);
}
};
What I would really suggest is investing in a parser, kind of like how Angular does it. That kind of thing would prevent your users from doing whatever the hell they want, introducing attack vectors, yadda, yadda, yadda.
Either manage your expectations or manage your user's expectations. eval and new Function() are not suitable for your requirements if you require mixed usage of explicit and non-explicit return statements in the same user-input. You will continue to find issues following either of these routes.
Simply searching for the word return is not sufficient either... var returning = true; or var a = 'return'; or /* return true */ true; will all throw false positives.
Managing your expectations: To do such a thing you require a form of lexer and parser, at which point you can do away with eval entirely and execute your own safe functions based on the parsed input. This is the best approach when execution of user input has to occur anyway as you can ensure that nothing gets executed you do not wish to permit. If you want to cover these sort of edge cases and permit strange user input then you must be prepared to increase the size and development time of your application. I have built a few applications executing user generated code and have always come to the conclusion this is the correct route to go down.
Managing your user's expectations: Provide a guide, tell them not to mix explicit returns with non-explicit returns, these are strange coding practices anyway. Better yet explicitly tell them to include or omit the return statement. There is no shame in asking your users to follow them, especially if it allows you to improve their experience elsewhere.
There I was thinking I'd only see problems like this at the code golf stack exchange :)
My solution is here: http://jsfiddle.net/hKq87/1
It essentially replaces the 'return' statement with an exception that has a special string prefixed to it. If we see that string, we know we are actually returning a value, and return it rather than re-raising the exception.
The reason I chose to throw an exception rather than replace the return statement with a function call was because it is hard to know where the JS code evaluated for the return really ends. It could be split across multiple lines, contain several special characters and may not even have the optional semi-colon at the end. So I concatenate a string to whatever the value being returned is and throw it, as the throw keyword doesn't require it's argument to be wrapped in parentheses.
In addition, throwing exceptions provides me a convenient way to immediately terminate execution of the code block, without halting other JS execution.
Here is the callback method:
var callback = function(userInput) {
var returned = undefined;
userInput = userInput.replace(/(^|[\(\\)[\]{};,\s])return(\s*[^\s;])?/gi, function(m, b, e){
return b + " throw '__RETURNED_VALUE'" +
(e !== undefined ? "+" + e : "");
});
try {
returned = eval(userInput);
} catch (e) {
if (e.indexOf("__RETURNED_VALUE") == 0) {
returned = e.substring("__RETURNED_VALUE".length) || undefined;
}
else {
throw e;
}
}
return returned;
}
The regex above accounts for variables that may end with the string "return", that we would not want to replace as it is not a return statement. It also allows for return statements within braces, without trailing semi-colons or at the very beginning/end.
One issue with the current method is that you can not use the (rare) comma operator in a return statement, or expect numerical values to be returned correctly. The last test case in the jsfiddle demonstrates this. An example from here:
//original
return 5 * 2 + 3, 22;
//modified
throw '__RETURNED_VALUE='+ 5 * 2 + 3, 22;
//apply * operator
throw '__RETURNED_VALUE='+ 10 + 3, 22;
//apply + operators
throw '__RETURNED_VALUE=103', 22;
//apply , operator
throw 22;
This problem can be avoided by completely eliminating the prefix '__RETURNED_VALUE=' and just replacing 'return' with 'throw'. However, this means that the code provided must run without throwing exceptions, which I thought to be a harder constraint than just crafting return statements to be simple (avoiding comma operators, non-parenthesized arithmetic, etc.). In addition, if a user ever creates a return statement that we can't handle with the current code, we conveniently throw an exception for it so it easily comes to our attention.
jsFiddle Demo
Lets assume your user can be a little smarter than the average bear. We are going to ask them to specifically provide an initial value and then a callback with an expression for that value.
The main benefit of doing this is that you avoid eval, and actually have a nice implementation that is re-usable as opposed to being subject to later refactoring.
This way also provides a separation of where the input comes from and where the examination comes from. Although the provided example only shows integer input, really it could be another call with absolutely no knowledge of the value aside that it needs to conform to the callback logic.
function expression(x,callback){
return callback(x);
}
out1.innerHTML = expression(8,function(x){
return x;
});
out2.innerHTML = expression(10,function(x){
return x;
});
out3.innerHTML = expression(10,function(x){
if(x === 10) return "yes"; "no";
});
out4.innerHTML = expression(8,function(x){
return x === 10 ? "yes" : "no";
});

How do I dynamically generate code that will transfer an object to another Node process

I'm building a node server that needs to execute code that might be unsafe. In order to achieve this I'm using a Sandbox API that blocks attacks and returns the result and output from a script. It uses a modified global object to keep access hidden from the Node global object (and the use of require... etc).
My specific need right now is to take an object that is defined by a user (this is all trusted, nothing from random users on the internet so security isn't the biggest concern at the moment, right now it's to get it working) and create a dynamic bit of code that will "transfer" the object along with their code to a child Node process for safe execution (the security here is so that any errors don't crash the main process).
My current goal is to take an object, like the following:
obj = {
defaultName: "Unnamed",
hello: function(name) {
if (typeof name === "undefined" || name === null)
name = this.defaultName;
echo("Hello, " + name + "!");
}
}
(This is very simplistic, it's for testing)
I'm using FJSON to serialize the functions for transfer as well. My attempt at serializing this for transfer with the code is as follows:
// "code" is the users code
// "obj" is the object above
// "Extend" is a function defined by the Child process
var str = FJSON.funkify(obj);
code = "var temp = FJSON.unfunkify(\"" + str + "\"); Extend(this, temp); temp = undefined; " + code;
After doing this, and attempting to write it to the child I get weird (and cryptic errors) like: "Unexpected token {" or (rarely and more cryptic) "Unexpected token ILLEGAL '" (which, this is confusing because I've verified that nowhere in the code am I inserting a ' and there are none in the test code).
The funkified string is {"defaultName": "Unnamed","hello":{"FUNCTION":true,"params":["name"],"body":"\n\r if (typeof name === \"undefined\" || name === null)\n\r name = this.defaultName;\n\r echo(\"Hello, \" + name + \"!\");\n\r "}}
And finally, for the sake of testing, I've tried serializing a simple object (without functions using JSON, and with functions using FJSON) and then attempting to run eval on the string in the Node REPL but I keep getting ... when I try eval(JSON.stringify(objWithoutFunctions)); and the same with the FJSON.
I've struggled with this problem for several hours now and can't think of any other things to try/check. Any suggestions are appreciated.
UPDATE
I still have been unable to determine the most efficient way to do this, as stringifying the object and transferring it along with code was not working and I was unable to get it to work nicely I've reverted to converting the object into code, essentially looping through the properties and assigning the variables manually. To provide example:
The object:
obj = {
prop: "ItsValue",
otherProp: true
};
Would become:
this.prop = "ItsValue"; this.otherProp = true;
I found a workaround as listed in the Update, I just converted the object into code. It could have been issues with the FJSON library which I've fixed since then. This is no longer an issue but I still welcome any answers that may be able to address the original problem.

JavaScript sleep [duplicate]

This question already has answers here:
What is the JavaScript version of sleep()?
(91 answers)
Closed 9 years ago.
Yes, I know - that question has thousands of answers. please, don't tell me about setTimeout method because - yes, everything is possible with that but not so easy as using sleep() method.
For example:
function fibonacci(n) {
console.log("Computing Fibonacci for " + n + "...");
var result = 0;
//wait 1 second before computing for lower n
sleep(1000);
result = (n <= 1) ? 1 : (fibonacci(n - 1) + fibonacci(n - 2));
//wait 1 second before announcing the result
sleep(1000);
console.log("F(" + n + ") = " + result);
return result;
}
if you know how to get the same result using setTimeout - tell me ;) fibanacci is pretty easy task, because there aren't more than 2 recursions, but how about n-recursions (like fib(1) + fib(2) + .. + fib(n)) and sleep after every "+"? Nah, sleep would be muuuuuch easier.
But still I can't get working example of implementing it. while (curr - start < time) { curr = (...) } is tricky, but it won't work (just stops my browser and then throw all console logs at once).
The question is asking how to implement sleep() in JavaScript, right?
function sleep(ms) {
var start = new Date().getTime(), expire = start + ms;
while (new Date().getTime() < expire) { }
return;
}
I just tested it like so:
console.log('hello');
sleep(5000);
console.log('world');
Works for me.
(As a meta comment: I landed here because I have a particular need for this function. Such needs do come up when you need to block while waiting for a value. Even in JavaScript.)
I dont fully understand what you're asking, but I'm going to answer this part:
if you know how to get the same result
using setTimeout - tell me
The fundamental difference is that sleep (as used in many other languages) is synchronous, while setTimeout (and many other JavaScript-concepts, like AJAX for example) are asynchronous. So, in order to rewrite your function we have to take this into account. Mainly, we have to use a callback to fetch the "return value", rather than an actual return-statement, so it will be used like this:
fibonacci(7, function(result) {
// use the result here..
});
So, as for the implementation:
function fibonacci(n, callback) {
console.log("Computing Fibonacci for " + n + "...");
var result = 0;
var announceAndReturn = function() {
setTimeout(function() {
// wait 1 second before announcing the result
console.log("F(" + n + ") = " + result);
callback(result); // "returns" the value
}, 1000);
};
// wait 1 second before computing lower n
setTimeout(function() {
if (n <= 1) {
result = 1;
announceAndReturn();
}
else {
var resultsLeft = 2;
var handler = function(returned) {
result += returned;
resultsLeft--;
if (resultLeft == 0)
announceAndReturn();
}
fibonacci(n-1, handler);
fibonacci(n-2, handler);
}
}, 1000);
}
I would also like to point out that, no, this is not an easier solution than using sleep. Why? Because this code is asynchronous and that's simply more complicated than synchronous code for what most people are used to. It takes practice to start thinking in that way.
The upside? It allows you to write non-blocking algorithms that outperforms their synchronous counterparts. If you haven't heard of Node.js before, you could check it out to further understand the benefits of this. (Many other languages have libraries for dealing with async IO as well, but as long as were talking about JavaScript..)
The trouble with a sleep() type function within a browser (or any other GUI environment for that matter) is that it is an event-driven environment, and wouldn't be able to sleep() in the way you're describing it.
The setTimeout() method works because it is creating an event, and setting the trigger for that event to be a point in time. Therefore the system can give over control of the waiting to the event handler and Javascript itself is free to carry on doing other things.
In the web browser, virtually everything works this way. Mouse click/hover/etc functions are event triggers. Ajax requests don't sit and wait for the response from the server; they set an event to trigger when the response is received.
Time based actions are also done with event triggers, using functions like setTimeout().
This is how it's done. In fact this is how it's done in pretty much any well-written GUI application, because all GUI interfaces must be able to respond to events such as mouse clicks virtually instantly.
A Javascript sleep() function (especially the way it's been implemented in another answer here!) would basically have the effect burn up your CPU cycles while it waited for the clock. The sleep() would remain the active process, meaning that other events may not be processed straight away - which means your browser would appear to stop responding to mouse clicks, etc for the duration of the sleep. Not a good thing.
setTimeout() is the way to go. There is always a way to do it; the resulting code may not be neat and linear like your example code, but event-driven code very rarely is linear - it can't be. The solution is to break the process down into small functions. you can even embed the subsequent functions inside the setTimeout() call, which may go some way to helping you keep your code at least having some appearance of being linear.
Hope that helps explain things a bit for you.
Just use a better algorithm without loops or recursion, and avoid the need for setTimeout() / sleep().
function fibonacci(n) {
return Math.round(Math.pow((Math.sqrt(5) + 1) / 2, Math.abs(n)) / Math.sqrt(5)) * (n < 0 && n % 2 ? -1 : 1);
}
Usage example:
// Log the first 10 Fibonacci numbers (F0 to F9) to the console
for (var i = 0; i < 10; i++) {
console.log(fibonacci(i));
}
Why do you want to 'sleep' while computing anything? Sleeping for any time is nearly always a bad idea in any language. It essentially tells the thread to stop doing anything for that period of time.
So, in a language like javascript that only has one thread (forgetting 'web workers'), what benefit would you reap for pausing ALL computation? It's a bad idea, forget it.
Now to the problem that you've written, though I don't think this is your actual problem. Why do you want to pause for a second while computing this sequence? Even to compute the first 6 numbers in the sequence, it's going to take 8 or so seconds. Why? What possible reason is there to pause for a second between recursive calls? Stop it. Remove it.
If you want to just yield the final result a second after it completes, then use setTimeout with a function uses the answer in some way.
function fib(n) {
...
result = fib();
...
setTimeout(function() {
console.log("Fib for " + n + " is " + result);
},1000);
}
Do not try to implement 'sleep'. Do not pause during computation.

Categories

Resources