Destroy an object after set time - javascript

I have been looking around for this but have turned up a blank
is it possible in javascript to create an instance of an object which has a set time to live, after which it would be destroyed?
a case would be where a item is added to an array every 5 seconds and shown in the visual, each item then should be removed after it have been in view for a minute. I hesitate to run a timeout function checking the array every second to clear them..

OOP FTW. Why not create some sort of self removing object?
function SelfRemover(){//constructor
};
SelfRemover.prototype.addTo = function(arr) {
var me = this;
arr.push(me); //adding current instance to array
setTimeout(function() { //setting timeout to remove it later
console.log("Time to die for " + me);
arr.shift();
console.log(arr);
}, 60*1000)
}
Usage
var a = [];
setInterval(function(){new SelfRemover().addTo(a); console.log(a);}, 5*1000);

Related

Javascript diff between 2 moment objects returns -1

So i want to take 2 times on button click, and then upon clicking second one i want to display time passed from first time to second click.
Format should be HH:MM:SS. Now i tried to display it in seconds, hours, days, with and without true, but it always returns -1 or 0.
Other object (vreme2) is just same code as vreme1 but a new object.
Both objects in console log show _isMomentObject: true, so i cant figure it out.
var vreme1;
var vreme2;
var pocetno;
var zavrsno;
(pocetno = function () {
document.getElementById("dolazak")
.value = moment().format('HH:mm:ss');
})();
setInterval(pocetno, 1000);
var dugme1 = document.getElementById('dolazak-btn');
dugme1.addEventListener('click', function () {
clearInterval(pocetno);
var vreme1 = moment();
dugme1.setAttribute('disabled', 'disabled');
});
var pocetnoBtn = document.getElementById('dolazak-btn');
var rez = vreme2.diff(vreme1, 'seconds', true);
console.log(rez);
} else {
alert('Prvo ste uneli vreme odlaska!');
}
});
Inside the function(){} for dugme1.addEventListener, you do var vreme1 = moment();. That declares a new local variable vreme1 and sets it, but this local variable is then also discarded at the end of the function.
Note that the local variable vreme1 is not the same as your global variable vreme1: they occupy different spots in memory, have a different lifecycle, and have independent values.
If you remove the var that is inside the function(){}, then it might work (but I can't verify, because the code that you provided is rather incomplete).

create new element from array until array is empty every second

Trying to create an element using items from an array that are randomly selected every other second until array is empty. I am stumped why my function works when i don't append the element to the dom but as soon as i add to the dom the array just gets larger and ends up crashing the dom.
My plan is to eventually create a new object that has the image, css with random xy position and then append a new element to the dom using the object values.
Basically i am trying to add random images to the dom every second and have them animate in and out until the array is empty.
Any help would be greatly appreciated, thank you.
"load": function(){
var imgArray = ['brain', 'mitochondria', 'microscope', 'beaker', 'beaker-2', 'scientist', 'cell', 'atom', 'dropper'];
window.setInterval(function(){
var imgItem;
if( imgArray.length >= 1 ) {
var index = Math.floor( Math.random()*imgArray.length );
console.log( imgArray[index] ); // Log the item
imgItem = ( imgArray[index] ); // Log the item
imgArray.splice( index, 1 ); // Remove the item from the array
// $('form').append('<img class="img-animation" src="img/science/'+ imgItem +'.svg" alt="'+ imgItem +'">');
}
}, 1000);
},
This is the console when i don't append new image:
home.js:11 beaker
home.js:11 dropper
home.js:11 microscope
home.js:11 beaker-2
home.js:11 atom
home.js:11 brain
home.js:11 scientist
home.js:11 cell
home.js:11 mitochondria
If i add the new image to the dom it will eventually crash and the loop goes on forever which makes no sense to me.
Well, you are setting an interval, it will keep calling itself to check the if every second long after the array is empty, even if thats not the issue I recommend you to do something like this:
var imgArray = ['brain', 'mitochondria', 'microscope', 'beaker', 'beaker-2', 'scientist', 'cell', 'atom', 'dropper'];
var getAllRandomly = function(arr) {
if (arr.length) {
var index = Math.floor(Math.random() * arr.length);
console.log(arr[index]); // Log the item
imgItem = (arr[index]); // Log the item
imgArray.splice(index, 1); // Remove the item from the array
setTimeout(function() {
getAllRandomly(arr);
}, 1000);
}
else {
console.log('Array is empty');
}
};
getAllRandomly(imgArray);
This way, the function will call itself and return one result every second until the array is empty.
Now going to the real problem:
Your 'load' function is probably being called multiple times, setting a lot of intervals with the same array. If the loop is really infinite then it might be calling itself somehow.
Try leaving just a console log on your load function and run your script to see if the log appears multiple times.

When should I use a JavaScript array in lieu of a JavaScript object literal?

This question may seem trivial but it's something that's been bothering me for a while so I thought I'd ask. Apologies in advance if this question seems silly/naive to you.
So in JavaScript, object literals {} are hash tables under the hood. Meaning that they have near constant time lookup and insertion. So the question I keep wondering is (outside of pure convenience) why would I ever use a JavaScript array in lieu of an object literal?
Take this example of creating a Queue in JavaScript;
1) First, we'll use an Object literal as our storage component;
var Queue = function() {
this.storage = {};
this.order = [];
this.length = 0;
this.add = function(item) {
this.storage[item] = 1;
this.order.push(item);
this.length++;
};
this.remove = function() {
var removed = this.order.shift();
delete this.storage[removed];
this.length--;
return removed;
};
this.contains = function(value) {
return this.storage[value] ? true : false;
};
this.size = function() {
return this.length;
};
};
2) Second, using an array as our Queue's storage component
var Queue2 = function() {
this.storage = [];
this.add = function(item) {
this.storage.push(item);
return this;
};
this.remove = function() {
return this.storage.shift();
};
this.contains = function(target) {
var clone = this.storage.slice(0);
clone.sort();
var recurse = function(low, high) {
if (high === low) return false;
var mid = Math.floor((high - low) / 2) + low;
if (clone[mid] === target) return true;
else if (clone[mid] > target)
return recurse(low, mid);
else if (clone[mid] < target)
return recurse(mid + 1, high);
};
return recurse(0, clone.length);
}
};
lets create two separate Queues;
var objQueue = new Queue();
var arrayQueue = new Queue2();
Now lets add 1 million random passwords to both our Queues.
for (var i = 0; i < 1000000; i++) {
objQueue.add(Math.random().toString(36).slice(2));
}
for (var i = 0; i < 1000000; i++) {
arrayQueue.add(Math.random().toString(36).slice(2));
}
Normally we would never have to do this all at one time. But yes, it's going to take a little longer to fill up our object Queue. We've had to create a separate array in our Queue constructor to keep track of the order. Yes, this is very annoying. Unfortunately, when adding keys as numbers to a JavaScript object, JavaScript auto-sorts the numerical keys. So if you add 4, then 6, then 2, then 1. The Object will look like this:
{ '1': 1, '2':1, '4':1, '6':1 }
and for a Queue, we want it to look like this:
{ '4': 1, '6':1, '2':1, '1':1 }
NOTE: This is not the case when adding strings. With strings, the order of addition is preserved so creating a separate array to preserve order is unnecessary. I'm not sure if this is intentional or just a mistake? But in this particular case, since we're creating a Queue and order matters, it's annoying. Which could be one reason people might prefer to just use an array for storage in this situation.
Removing from the queue will have the same time complexity in both cases because we're always removing the first value. No big deal there.
But what happens if we want to search our Queue? This probably goes against the nature of what a Queue is supposed to be used for(does it??? I dunno, maybe our Queue is a priority queue, we're tired of waiting, and we want to search where our number is in the queue) but let's just say we want to search this giant Queue we've created.
Lets add a value value to the end of both our Queues that is not random:
objQueue.add('bvflq9kk61xajor');
arrayQueue.add('bvflq9kk61xajor');
Now lets search for this value in our array Queue and measure the time:
var start1 = new Date().getTime();
var result1 = arrayQueue.contains('bvflq9kk61xajor');
var end1 = new Date().getTime();
var time1 = end1 - start1;
Now lets search for this value in our object Queue and measure the time:
var start2 = new Date().getTime();
var result2 = objQueue.contains('bvflq9kk61xajor');
var end2 = new Date().getTime();
var time2 = end2 - start2;
RESULTS
console.log('Execution time for Array Queue: ' + time1);
console.log('RESULT:', result1);
//Execution time for Array Queue: **3873**
//RESULT: true
console.log('Execution time for Object Queue: ' + time2);
console.log('RESULT', result2);
//Execution time for Array Queue: **0**
//RESULT: true
The main reason the array Queue takes so much longer to execute is because I'm having to sort it before performing a Binary Search on it. Binary search is fast but requires the array to be pre-sorted. I could pre-sort the array each time I add a new value to the array Queue but then this would defeat the purpose of what a Queue is: FIFO(first in first out) and we'd start running into the same order issue we have with objects.
So I guess the real question I'm wondering is why do we even bother with arrays when we can do most things we need to do with a JS Object? Especially when JS objects are hash tables and thus we get near constant time lookup with them.
I guess it wouldn't matter so much if you never planned on searching through your data but when is that ever the case?? When you fill up an object or an array with data, you're inevitably going to want to search your data? Yes? No? Am I totally wrong here? And when you go to search this data, you'll be stoked to have stored it in what's essentially a hash table. Right?
Am I totally wrong here? Missing something? Would love some feedback on when to use arrays and when to use object literals. I'm guessing one case would be when your data set is small.

setInterval() speeds up when using multiple from object method

I have been having problems with my setIntervals(). I know these issues appear a lot but I can't seem to work out what the exact problem with my implementation is. Every time I instantiate a new Obstacle() it clears the set interval used to rotate the instance of the obstacle, and the next instantiation of the obstacle seem to rotate twice as fast! I'm sure it's to do with scope but I'm a relative beginner so I'm not quite sure what's going on here. Any more info can be provided.
var obstacleCount = 1;
function Obstacle(){
this.angle = 0;
this.id = obstacleCount;
this.elPrefix = "cookie-";
this.el = '.' + this.elPrefix + this.id;
$('#game-wrapper').append('<div class="' + this.elPrefix + this.id + '"></div>');
obstacleCount += 1;
}
var intervals = new Array();
Obstacle.prototype.roll = function() {
self = this;
intervals[self.id] = setInterval(function(){
self.angle -= 3;
$(self.el).rotate(self.angle);
}, 5);
$(self.el).animate({
right: 1000
}, 4000, 'linear', function(){
$(self.el).remove();
clearInterval(intervals[self.id]);
});
};
var obstacles = new Array();
setInterval(function(){
obstacleID = obstacleCount;
obstacles[obstacleID] = new Obstacle();
obstacles[obstacleID].roll();
}, 1000);
In most games there is a single update loop that handles all of the update logic for your game. I would recommend using a single interval in which all objects are updated instead of giving each object it's own scheduled update via setInterval. You gain a few advantages from the update loop method:
Don't have to keep track of intervals.
Since since setInterval is not consistant with timing (it fires when the main script is finished executing and has some extra time before the next go around, but only if it's interval time is up. This means you cannot completely rely on it's timing being what you asked it to be.) you are better off having all your objects updated at the time so you are as consistant as you can be.
General pseudo code to get you started:
initialize objects
add all objects to an array
setInterval(updateObjects, 30);
updateObjects(){
for each object in array
object.roll();
}

Play functionality in nested loops Javascript

I am trying to build play functionality using JavaScript to play different colors for my attribute values on map. The basic logic, I am building using simple for loop does not work for me as the loop is played so fast and I only get display last value on Map.
Example:
//Hash of my Values
var myHash = {};
myHash['1'] = [10,100];
myHash['2'] = [20,200, 30];
myHash['3'] = [40,300, 4, 5];
function startPlaying() {
for (item in myHash) {
var myValues= myHash[item];
var timeOut=setTimeout(function(){
animate(myValues,item);
},1000);
}
}
function animate(myValues,item) {
for(i in myValues) {
//calling my function for each value to play on map with different styles.
playMyMap();
}
}
I was expecting here that my function startPlaying will fire timeout function three times(for number of items with 1 sec delay) with corresponding myValues and item and It will keep on iterating over myValues individually for three items.
But this doesn't work for me beacuse the myValues gets messed up while each call of setTime out function.
Could anyone please give me an idea here, how can I build such functionality?
var timeOut=setTimeout(function(){
animate(myValues,item);
},1000);
}
Will trigger 3 times, but all after 1 second. If you keep a counter you have to do the 1000*counter to have 1 animate function each second.
The below example uses the item as the multiplyer because you start your index with 1. Normally array's start at index 0. If you change your first item to index 0, just do 1000 * (item + 1) to start with 1 second.
Try this:
function startPlaying() {
for (item in myHash) {
var myValues= myHash[item];
var timeOut=setTimeout(function(){
animate(myValues,item);
},1000 * item );
}
}

Categories