-2

I want to be able to make the console.log(key); make the log every 5 seconds, at the moment there is no delay and all the data gets logged at the same time.

//the location of my usres table var ref = new Firebase('https://myapp.firebaseIO.com/users/'); //ask fire base to get the records just once ref.once("value", function (snapshot) { //loop through the retuned records snapshot.forEach(function (childSnapshot) { // get just the value for the key var key = childSnapshot.key(); // log the key - this will be changed to send the value to another function console.log(key); }); }) 

The console.log above give me thousands of Id's, I need to pass these Id's to another function, If I pass all these id's all at one time the next function will blow up, so I want to pass them slowly, one by one to the next function. other ideas welcomed.

3
  • You'll need to use setInterval() -- see stackoverflow.com/questions/18070659/… Commented Jan 8, 2016 at 19:00
  • What is the real goal here? This looks highly artificial. See the XY Problem. Could probably save a lot of time by explaining what you're actually trying to achieve. Commented Jan 8, 2016 at 21:26
  • The for each is returning thousands of user id's, if I pass all the user id's to the next function at one time the script will blow up, so my thinking is to pass the id's to the next function every 5 seconds, which will give the next function plenty of time to complete. Commented Jan 9, 2016 at 1:02

4 Answers 4

1

Use closure to get the value of key of current iteration after the setTimeout

Try this:

 var ref = new Firebase('https://myapp.firebaseIO.com/users/'); ref.once("value", function(snapshot) { snapshot.forEach(function(childSnapshot, index) { var key = childSnapshot.key(); setTimeout((function(key) { return function() { console.log(key); } })(key), 5000 * index); }); }); 
Sign up to request clarification or add additional context in comments.

1 Comment

I tried but the log writes all the data to the console at the same time with no delay
0
var ref = new Firebase('https://myapp.firebaseIO.com/users/'); ref.once("value", function (snapshot) { for(var i=0; i<snapshot.lenght;i++){ var childSnapshot = snapshot[i]; var key = childSnapshot.key(); setTimeout(function () { console.log(key); }, 5000); // will stop the loop for 5 seconds every time } }); 

7 Comments

I tried but the log writes all the data to the console at the same time with no delay
Instead of a .forEach function. try using a normal for loop; I cannot give you this an answer but as a suggestion since I had this similar issue in the past using forEach loop on the DOM, and using normal for loop fixed my issue. I cannot say why or how it happened since I did not searched further.
Im so set in my ways with the for each loop I cant even see how to change it for a for loop! Any pointers would be great
For some reason i get no errors and no console log?
A Firebase snapshot is not an array, so you cannot loop over its children like this. firebase.com/docs/web/api/datasnapshot snapshot.forEach() will loop over the children.
|
0

Maybe you mean a custom array iterator that iterates to the next element in the array after a specified delay. I made one using functional programming principals to promote re usability. see below

/* * makeTimedForEach * * this will create an array itererator that will loop through an array * at a specified timeout delay. * * @param {array} arr array to iterate * * @returns {Function} function to pass in callback and delay */ function makeTimedForEach(arr) { return function timedForEach(fn, delay) { var ii = 0; function iterate() { if (ii < arr.length) { // call the callback injecting the current element, index and array like native forEach fn.call( arr[ii], arr[ii], ii, arr ); ii++; // call iterate again setTimeout(iterate, delay); } } // call for the first time you could add a setTimout here // if you needed a delay at the start // setTimeout( iterate, delay ); iterate(); } } // Snapshot mock function Snapshot(key) { this._key = key; } Snapshot.prototype = { key: function(){ return this._key; } } var // a mock of the snapshot you get returned from `new FireBase` snapshot = [new Snapshot('one'), new Snapshot('two'), new Snapshot('three')], // create the iterator snapshotTimedForEach = makeTimedForEach(snapshot); // call the iterator passing in the callback and the delay time snapshotTimedForEach(function(childSnapshot, ii, arr) { console.log( childSnapshot.key(), childSnapshot, ii, arr ); }, 1000);
<script src="http://codepen.io/synthet1c/pen/WrQapG.js"></script>

original answer:

Im not sure if this is what you need, I cant see a point in logging the same result every 5 seconds. It seems you may want to poll the firebase api every 5 seconds

var ref = new Firebase('https://myapp.firebaseIO.com/users/'); ref.once("value", function(snapshot) { snapshot.forEach(function(childSnapshot) { var key = childSnapshot.key(); // you can use setTimeout that recursively calls itself, // setTimeout will run the callback after the time has passed // and wont lock up your thread like setInterval function log() { console.log(key); setTimeout( log, 5000); } // call log for the first time setTimeout( log, 5000); }); })

4 Comments

I tried but the log writes all the data to the console at the same time with no delay
thats weird. give me a sec, I'll use some dummy data. actually on second thought did you want to iterate over the forEach every 5 seconds are delay the console log for 5 seconds then continue each 5 seconds.
The for each is returning thousands of user id's, if I pass all the user id's to the next function the script will blow up, so my thinking is to pass the id's to the next function every 5 seconds, which will give the next function plenty of time to complete.
You really need to add more information into the question. That is relevant information that would have got you a better solution of chucking the array and processing in batches allowing other events to still fire so the thread is not completely blocked up until all records are processed. The script I provided will do something every 5 seconds and operate like a normal forEach so you could do what you want but it's not the best solution. just chuck the data pass that array to makeTimedForEach
0

You can use setTimeout and recursive function like this:

function values(obj) { if (obj instanceof Array) { return obj.slice(); } else { return Object.keys(obj).map(function(key) { return obj[key]; }); } } ref.once("value", function (snapshot) { var array = values(snapshot.val()); (function process() { var item = array.shift(); if (item) { var key = item.key(); console.log(key); setTimeout(process, 5000); } })(); }); 

4 Comments

I tried the above and I get FIREBASE WARNING: Exception was thrown by user callback. TypeError: snapshot.slice is not a function
@Bill try snapshot.val().slice()
FIREBASE WARNING: Exception was thrown by user callback. TypeError: snapshot.val(...).slice is not a function
@jcubic: Your approach sounds good. But snapshot.val() likely (given that OP is missing a JSON sample) returns an associative array of keys (Firebase uids or push ids) and values (the actual user data). In that case it is common to loop over the values with a var val = snapshot.val(); Object.keys(val).forEach(function(key) { val[key]...

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.