Change value from outside of the function - javascript

I have something like the following:
function somefunc() {
function anotherfunc() {
...
if ( m > ...
...
}
$(window).on("scroll", anotherfunc);
}
somefunc();
I want to be able to change m value in execution of somefunc("value") (last step in above code snippet - somefunc();), so it would transfer the m value to the anotherfunc - but I don't know if I can(able) do so and would like to ask some for your help.

function somefunc(m) {
function anotherfunc() {
console.log(m)
}
$(window).on("scroll", function(){
anotherfunc(m);
});
}
somefunc(1);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

Like commented, declare m outside the functions:
var m = 1;
console.log('Outside functions: ' + m);
function someFunc() {
m += 1;
console.log('someFunc: ' + m);
function otherFunc() {
m += 1;
console.log('otherFunc: ' + m);
}
otherFunc();
}
someFunc();

Related

Return value inside a setInterval

I want to return a value inside a setInterval. I just want to execute something with time interval and here's what I've tried:
function git(limit) {
var i = 0;
var git = setInterval(function () {
console.log(i);
if (i === limit - 1) {
clearInterval(git);
return 'done';
}
i++;
}, 800);
}
var x = git(5);
console.log(x);
And it's not working.
Is there any other way?
What I'm going to do with this is to do an animation for specific time interval. Then when i reached the limit (ex. 5x blink by $().fadeOut().fadeIn()), I want to return a value.
This is the application:
function func_a(limit) {
var i = 0;
var defer = $.Deferred();
var x = setInterval(function () {
$('#output').append('A Running Function ' + i + '<br />');
if (i == limit) {
$('#output').append('A Done Function A:' + i + '<br /><br />');
clearInterval(x);
defer.resolve('B');
}
i++;
}, 500);
return defer;
}
function func_b(limit) {
var c = 0;
var defer = $.Deferred();
var y = setInterval(function () {
$('#output').append('B Running Function ' + c + '<br />');
if (c == limit) {
$('#output').append('B Done Function B:' + c + '<br /><br />');
clearInterval(y);
defer.resolve('A');
}
c++;
}, 500);
return defer;
}
func_a(3).then( func_b(5) ).then( func_a(2) );
This is not functioning well, it should print A,A,A,Done A,B,B,B,B,B,Done B,A,A,Done A but here it is scrambled and seems the defer runs all function not one after the other but simultaneously. That's why I asked this question because I want to return return defer; inside my if...
if (i == limit) {
$('#output').append('A Done Function A:' + i + '<br /><br />');
clearInterval(x);
defer.resolve('B');
// planning to put return here instead below but this is not working
return defer;
}
Do you expect it to wait until the interval ends? That would be a real pain for the runtime, you would block the whole page. Lots of thing in JS are asynchronous these days so you have to use callback, promise or something like that:
function git(limit, callback) {
var i = 0;
var git = setInterval(function () {
console.log(i);
if (i === limit - 1) {
clearInterval(git);
callback('done');
}
i++;
}, 800);
}
git(5, function (x) {
console.log(x);
});
Using a promise it would look like this:
function git(limit, callback) {
var i = 0;
return new Promise(function (resolve) {
var git = setInterval(function () {
console.log(i);
if (i === limit - 1) {
clearInterval(git);
resolve('done');
}
i++;
}, 800);
});
}
git(5)
.then(function (x) {
console.log(x);
return new Promise(function (resolve) {
setTimeout(function () { resolve("hello"); }, 1000);
});
})
.then(function (y) {
console.log(y); // "hello" after 1000 milliseconds
});
Edit: Added pseudo-example for promise creation
Edit 2: Using two promises
Edit 3: Fix promise.resolve
Try to get a callback to your git function.
function git(limit,callback) {
var i = 0;
var git = setInterval(function () {
console.log(i);
if (i === limit - 1) {
clearInterval(git);
callback('done') // now call the callback function with 'done'
}
i++;
}, 800);
}
var x = git(5,console.log); // you passed the function you want to execute in second paramenter

How to reference a setInterval() id from itself in JavaScript, without help of an outer scope?

Just out of curiosity: can I reference a setInterval() id from itself, without having to store itself in a variable?
So, instead of doing this:
function counter() {
console.log(id + ": " + count++);
if (count > 10)
clearInterval(id);
}
var count = 0;
var id = setInterval(counter, 250);
I'd be doing this:
function counter() {
console.log(aReferenceToItsOwnId + ": " + count++);
if (count > 10)
clearInterval(aReferenceToItsOwnId);
}
var count = 0;
setInterval(counter, 250);
Which would, just in example, allow me to reuse the function simply, like this:
setInterval(counter, 200);
setInterval(counter, 250);
setInterval(counter, 333);
No, you can't. The only place accessible to your code that the id is tracked is the return value of the setInterval function.
If you want to reuse the function, you could wrap it like:
function startCounter(time) {
function counter() { ... }
var count = 0;
var id = setInterval(counter, time);
}
startCounter(200);
startCounter(250);
startCounter(333);
Use additional parameter of function to do this.
var si1=setInterval(function(){counter(1);},200);
var si2=setInterval(function(){counter(2);},250);
var si3=setInterval(function(){counter(3);},333);
function counter(id)
{
...
clearInterval(window['si'+id]);
...
}
As the other answers state, it is impossible. However, you could create a helper function to greatly ease that fact.
Code
function timer(callback, interval) {
var id = setInterval(function() {
callback.call({ id: id });
}, interval);
};
Usage
var count = 0;
function counter() {
console.log(this.id + ' - ' + count++);
if (count > 10) clearInterval(this.id);
};
timer(counter, 250);
timer(counter, 300);

JS Execute functions in order, while passing the next function as an argument

I am trying to eliminate the "callback pyramid of DOOM" by doing this:
$$( //my function
function(next) { // <- next is the next function
setTimeout(next,1000); // simple async function
},
function(next){ // this function is the previous's function "next" argument
waitForSomethingAndReturnAValue(next, "I am a parameter!");
},
function(aValue){
console.log("My value is:" + aValue);
}
);
BUT I have been fiddling for about an hour, and my code doesn't work, any help? this is what I got so far:
function $$(){
for (a in arguments){
arguments[a] = function(){
arguments[a](arguments[Math.max(-1, Math.min(a+1, arguments.length-1))]);
};
}
arguments[0]();
}
Something like this works:
function $$() {
if (arguments.length <= 0) return;
var args = Array.prototype.slice.call(arguments); // convert to array
arguments[0](function () { $$.apply(null, args.slice(1)); });
}
$$(function(next) { alert("one"); next() }, function (next) { alert("two"); next() });
http://jsfiddle.net/Cz92w/
You can try this:
function $$(){
var i=0, ret, args = [].slice.call(arguments);
var obj = {
next: function() {
ret = args[i++].call(obj, ret);
}
};
obj.next();
}
and use it like this:
$$(
function() {
console.log(Date() + ' - Function 1');
setTimeout(this.next, 1e3); // simple async function
},
function(){
console.log(Date() + ' - Function 2');
return waitForSomethingAndReturnAValue(this.next, "I am a parameter!");
},
function(aValue){
console.log(Date() + ' - Function 3');
console.log("My value is:" + aValue);
}
);
function waitForSomethingAndReturnAValue(callback, param) {
setTimeout(callback, 2e3);
return param + param;
}
Basically, the returned value in each function is passed as the argument to the next one. And the reference to the next function is this.next.

Execute a function BEFORE ANY function is executed

What I want to do is to execute a function automatically every time BEFORE ANY function is executed in JS, regardless if it's a custom or native function if possible.
ie.
whatIWant(functionName){
return console.log('called before '+functionName);
}
function blah(){
return console.log('called blah');
}
function meh(){
return console.log('called meh');
}
alert('woot');
blah();
//will output :
//called before blah
//called blah
meh();
//will output :
//called before meh
//called meh
alert();
//will output :
//called before alert
//will pop up dialog: woot
I do not want to do the following:
Function.prototype.onBefore = function(){};
blah.onBefore();
is it even possible to do what I am asking for? any suggestions, read, or w/e?
Thanks in advance.
What about just providing your function as a callback to whatIWant like this:
function whatIWant(fn) {
var fnName = fn.toString();
fnName = fnName.substr('function '.length);
fnName = fnName.substr(0, fnName.indexOf('('));
console.log('called before ' + fnName);
fn();
}
function meh() {
console.log('called meh');
}
function blah() {
console.log('called blah');
}
whatIWant(meh);
whatIWant(blah);
whatIWant(alert)
what do you guys think about this solution? :)
function bleh(){
console.log('exe a');
}
function limitFn(fn,n) {
var limit = n ;
var counter = 1 ;
var fnName = fn.toString();
fnName = fnName.substr('function '.length);
fnName = fnName.substr(0, fnName.indexOf('('));
return function(){
if(counter <= limit) {
console.log(counter + ' call before ' + fnName + ' limit ' + limit);
counter++;
fn();
} else {
console.log('limit of ' + limit + ' exes reached') ;
}
};
}
limited = limitFn(bleh,2);
limited();
limited();
limited();
limited();

Global & Local variables in Javascript

I have one variable and two functions . The variable is used by both. and the first function is changing the variable value (globally) each time it's used by it . This is what I want but it is not working with me .
x = 1;
function f1()
{
x = x + 1;
// use x
}
function f2()
{
// use x
}
I've read other threads but x is always 1 which is very frustrating :|
added: actual code
<script type="text/javascript">
function S4() {
return (((1 + Math.random()) * 0x10000) | 0).toString(16).substring(1);
}
function guid() {
return (S4() + S4() + ";" + S4() + ";" + S4() + ";" + S4() + ";" + S4() + S4() + S4());
}
P = '';
function Save() {
P = guid();
$('#btnBrowse').uploadifyUpload();
}
$(document).ready(function () {
$('#txtText').elastic();
$('#btnBrowse').uploadify({
'uploader': '../uploadify.swf',
'script': '../uploadify.ashx',
'cancelImg': '/uploadify/cancel.png',
'folder': '../images/Albums/',
'multi': true,
'fileDesc': 'Web Image Files (.JPG, .GIF, .PNG)',
'fileExt': '*.jpg;*.gif;*.png',
'scriptData': { 'Album_ID': P },
'buttonText': 'Upload Images'
});
});
</script>
so the variable is P . and it is used by jquery function (uploadify) . each time I excute
Save function I expect I get a new value for variable P . But is always the same ??
The problem is the time when you execute the code. The uplodify options are set on page load (which includes that P is passed on page load) and as P is a string, changing P later (through save()) will not change the value you passed.
You can solve this by passing a reference to the object as option, instead of the string Edit: Didn't work.
The plugin provides a uploadifySettings [docs] method to change the settings of an uploadify instance. Use it to update the scriptData settings:
function Save() {
$('#btnBrowse').uploadifySettings('scriptData', {'Album_ID' : guid()}, true);
$('#btnBrowse').uploadifyUpload();
}
Maybe this fiddle can help you understand global scope a little better: http://jsfiddle.net/XFx27/1/
var x = 0;
function add1()
{
x = x + 1;
}
function show()
{
alert(x);
}
add1();
show(); //alerts 1
add1();
show(); //alerts 2
Your missing parens () after your functions function funcName()
x = 1;
function f1()
{
x = x + 1;
// use x
}
function f2()
{
// use x
}
// x is 1
f1();
// x is 2
f2();
firstly, the f1 function should be:
function f1(){
x = x + 1;
// use x
}
var x;
function f1(){
x = x + 1;
console.log(x);
}
function f2(){
console.log(x);
}
f1(); // 2
f2(); // 2
I tried the code in chrome console and I think it really works.

Categories