Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 7 years ago.
Improve this question
I'm trying to do something really simple but not able to achieve this.
var Dummy = function() {
self = this;
setTimeout(function() {
if(self.render) {
self.render();
}
}, 10);
};
var test = new Dummy();
test.render = function() {
console.log('Make constructor call this method? ');
}
How can I make this work without settimeout?
Goal: Based on the function names attached to instance, I want to call them in particular order.
eg:
var Dummy = function() {
if(function1) {
function1();
}
if(function2) {
function2();
}
};
I am not sure what you are trying to do, but if what you want to do is call multiple functions (in order) when you instantiate an object instance of Dummy:
var Dummy = function() {
for (var i = 0; i < arguments.length; i++) {
if (typeof arguments[i] === "function") {
arguments[i]();
}
}
}
var function1 = function() { console.log('Func 1 executed!'); }
var function2 = function() { console.log('Func 2 executed!'); }
var d = new Dummy(func1, func2, 'maybe a string also');
// log
'Func1 executed!'
'Func2 executed!'
You question isn't entirely clear, but I assume you have a function that you want to have called as soon as your object has been instantiated. The simplest way to do this is to pass the function as an argument.
Something like:
var Dummy = function(myFunction) {
self = this;
self.render = myFunction; // if you want to be able to call it again later
self.render(); // if you want to call it now
};
var test = new Dummy(function() {
console.log('Make constructor call this method? ');
});
var anotherTest = new Dummy(function() {
console.log("this instance will have a different render function");
});
Now, of course, this can be extended to handle any number of functions passed in:
var Dummy = function(func1, func2) {
// Note: you may want to check the arguments actually are functions
if (func1) {
func1();
}
if (func2) {
func2();
}
}
var test = new Dummy(function() { console.log("1"); },
function() { console.log("2"); });
Or you could pass in an array of functions in the order you want them executed:
var Dummy = function(funcArray) {
for (var i=0; i < funcArray.length; i++) {
funcArray[i]();
}
}
var test = new Dummy([function() { console.log("1"); },
function() { console.log("2"); }]);
Or you could pass in an object with the functions (and names) you want:
var Dummy = function(funcObject) {
if (funcObject.func1) {
funcObject.func1();
}
if (funcObject.func2) {
funcObject.func2();
}
}
var test = new Dummy({ func1 : function() { console.log("1"); },
func2: function() { console.log("2"); });
Becuase you are adding render() method on the Dummy instance (test) and you are not even calling that render() method.
I think you need to change to the following (assuming you don't want to use prototype to create the render() method):
var Dummy = function() {
this.render = function() {
console.log('Make constructor call this method called? ');
};
self = this;
setTimeout(function() {
console.log(self);
self.render();
}, 10);
};
var test = new Dummy();
Related
This is the question:
Define a function named print which just print out the parameters it gets.
But it will not print out anything if it's called normally.
Only in a setTimeout callback will become effective.
e.g:
setTimeout(function() {
print('123'); //===> 123
});
print('456'); //===> nothing output
I have one solution but I don't think it's a good way, I rewrite the setTimeout.
I want a better solution curiously.
var print = function() {
'use strict';
var __origSetTimeout = window.setTimeout;
window.setTimeout = function(fn, delay) {
var _fn = new Function(`(${fn.toString().replace(/print\(/g, 'print.call(this,')}).call(this);`);
return __origSetTimeout.call(window, _fn.bind({
isFromSetTimeout: true
}), delay);
};
return function print(word) {
if (!this || !!this && !this.isFromSetTimeout) return;
console.log(word);
};
}.call(null);
You can use scope to solve this, for example
function A(){
let print = function(str){
console.log(str);
}
this.setTimeout = function(){
setTimeout(function(){
print('123');
}, 1000);
}
}
let a = new A();
a.setTimeout();
You could use a monkey patch for an extension of the print function with an additional check for a this object and a property for printing.
// simple function with output
function print(s) {
console.log(s);
}
// apply monkey patch
void function () {
var p = print;
print = function () {
if (this && this.timeout) {
p.apply(this, arguments);
}
}
}();
// bind additional information
setTimeout(print.bind({ timeout: true }, '123'));
print('456');
pardon my javascript ignorance: Why can't i do something like this in javascript? Running this tells me that theCalled is not defined. the order of the functions doesn't matter of course.
var myObj = {
theCaller: function() {
console.log('The Caller');
theCalled();
},
theCalled: function() {
console.log("i was called");
}
}
myObj.theCaller();
Add "this" before you call .theCalled()
var myObj = {
theCaller: function() {
alert('The Caller');
this.theCalled();
},
theCalled: function() {
alert("i was called");
}
}
myObj.theCaller();
I'm bound to use native javascript (although a jQuery solution can also work if I convert it to native javascript).
Also, I have no handles to existing AJAX requests so I can't access them directly.
I am searching for something like:
var ajaxRequestsInProgress = document.getAllAjaxRunning();
ajaxRequestsInProgress[1].getStatus(); // will return the status of the request, for example
so I can access this object and check / manipulate existing ajax requests.
This is, shall we say, a little tricky. There is no native way to do it. So we need to do a bit of hacking, modifying the native XMLHttpRequest functions. Something like this:
var getAJAXRequests = (function() {
var oldSend = XMLHttpRequest.prototype.send,
currentRequests = [];
XMLHttpRequest.prototype.send = function() {
currentRequests.push(this); // add this request to the stack
oldSend.apply(this, arguments); // run the original function
// add an event listener to remove the object from the array
// when the request is complete
this.addEventListener('readystatechange', function() {
var idx;
if (this.readyState === XMLHttpRequest.DONE) {
idx = currentRequests.indexOf(this);
if (idx > -1) {
currentRequests.splice(idx, 1);
}
}
}, false);
};
return function() {
return currentRequests;
}
}());
It can be called with getAJAXRequests().
You can see it in action on jsFiddle.
I know you didn't specifically ask for a Mootools solution, but I've done something similar which I thought I'd share here for others' reference. I achieve this by overriding the various request methods. I'm currently using version 1.5.1, but this or something similar should work on other versions.
(function() {
var requestCounter = 0,
send = Request.prototype.send,
cancel = Request.prototype.cancel,
onSuccess = Request.prototype.onSuccess,
onFailure = Request.prototype.onFailure,
timeout = Request.prototype.timeout;
var increment = function() {
++requestCounter;
};
var decrement = function() {
--requestCounter;
if (requestCounter < 0) {
requestCounter = 0;
}
};
Request.implement({
send: function() {
increment();
return send.apply(this, arguments);
},
cancel: function() {
decrement();
return cancel.apply(this, arguments);
},
onSuccess: function() {
decrement();
return onSuccess.apply(this, arguments);
},
onFailure: function() {
decrement();
return onFailure.apply(this, arguments);
},
timeout: function() {
decrement();
return timeout.apply(this, arguments);
}
});
Request.getRunningCount = function() {
return requestCounter;
};
})();
Now every time a request is made, the counter will increment and when it's complete, it will decrement.
var request1 = new Request(...);
var request2 = new Request(...);
request1.send();
request2.send();
console.log(Request.getRunningCount()); // 2
request1.cancel();
console.log(Request.getRunningCount()); // 1
// request2 completes
console.log(Request.getRunningCount()); // 0
This is probably not possible but maybe some of the stackoverflow geniuses can find a solution :)
W would like to have a function like this:
var myCrazyFunc;
myCrazyFunc = function (param1, callback) {
var funcId;
// I would like to get an Id of the function passed by callback
// which will be different for those two calls in example below
funcId = getFuncId(callback);
callback();
};
myCrazyFunc("param1", function () {
dosomething1;
});
myCrazyFunc("param1", function () {
dosomething2;
});
Please don't ask why I need that :) Simply it would simplify my code if that was possible.
Here is the function I made:
var myCrazyFunc;
var latestID = 0;
var funcToID = {};
function getFuncId(f) {
if (f in funcToID) {
return funcToID[f];
}
funcToID[f] = ++latestID;
return latestID;
}
myCrazyFunc = function(param1, callback) {
var funcId;
// I would like to get an Id of the function passed by callback
// which will be different for those two calls in example below
funcId = getFuncId(callback);
console.log(funcId);
callback();
};
myCrazyFunc("param1", function() {
'a';
});
myCrazyFunc("param1", function() {
'b';
});
this example would log:
1
2
I you run it with the same function code you get the same id, like here:
myCrazyFunc("param1", function() {
'a';
});
myCrazyFunc("param1", function() {
'a';
});
Ouput:
1
2
I hope that's ok.
Let's assume that I have the timeout ID returned from setTimeout or setInterval.
Can I get, in some way, the original function or code, associated with it?
Something like this:
var timer_id = setTimeout(function() {
console.log('Hello Stackoverflowers!');
}, 100000);
var fn = timer_id.get_function(); // desired method
fn(); // output: 'Hello Stackoverflowers!'
You can put a wrapper around setTimeout - I just threw this one together (after a few iterations of testing...)
(function() {
var cache = {};
var _setTimeout = window.setTimeout;
var _clearTimeout = window.clearTimeout;
window.setTimeout = function(fn, delay) {
var id = _setTimeout(function() {
delete cache[id]; // ensure the map is cleared up on completion
fn();
}, delay);
cache[id] = fn;
return id;
}
window.clearTimeout = function(id) {
delete cache[id];
_clearTimeout(id);
}
window.getTimeout = function(id) {
return cache[id];
}
})();
NB: this won't work if you use a string for the callback. But no one does that, do they..?
Nor does it support passing the ES5 additional parameters to the callback function, although this would be easy to support.
var timeouts = {}; // hold the data
function makeTimeout (func, interval) {
var run = function(){
timeouts[id] = undefined;
func();
}
var id = window.setTimeout(run, interval);
timeouts[id] = func;
return id;
}
function removeTimeout (id) {
window.clearTimeout(id);
timeouts[id]=undefined;
}
function doTimeoutEarly (id) {
func = timeouts[id];
removeTimeout(id);
func();
}
var theId = makeTimeout( function(){ alert("here"); }, 10000);
console.log((timeouts[theId] || "").toString());
timeouts[theId](); // run function immediately, will still run with timer
You can store each timeout function in an object so that you can retrieve it later.
var timeout_funcs = {};
function addTimeout(func,time) {
var id = window.setTimeout(func,time);
timeout_funcs[id] = func;
return id;
}
function getTimeout(id) {
if(timeout_funcs[id])
return timeout_funcs[id];
else
return null;
}
function delTimeout(id) {
if(timeout_funcs[id]) {
window.clearTimeout(timeout_funcs[id]);
delete timeout_funcs[id];
}
}
the IDs returned from setTimeout/setInterval are just numbers, they have no properties or methods other than those that every other number would have. If you want to get that function, you can declare it first instead of using an anonymous:
var myFunc = function() {
console.log('Hello Stackoverflowers!');
};
var timer_id = setTimeout(myFunc, 100000);
myFunc(); // output: 'Hello Stackoverflowers!'
clearTimeout(timer_id); // unless you want it to fire twice