1

Given this code:

var o = {
  k1: 'v1',
  k2: 'v2',
  k3: 'v3'
};

var stupidf = function(k, v, callback) {
  setTimeout(function() {
     console.log(k + "=" + v);
     callback();
  }, 2000};
};

What's the best way to produce the output:

// after 2 seconds
stdout: k1=v1
// after 4 seconds
stdout: k2=v2
// after 6 seconds
stdout: k3=v3

With an array, you'd make a copy and push() it about with callbacks, but I can't really see how to do this with an object.

Phrogz
  • 296,393
  • 112
  • 651
  • 745
Aaron Yodaiken
  • 19,163
  • 32
  • 103
  • 184

1 Answers1

1

You're assuming that the iteration of entries in o has a guaranteed order; it does not. Assuming you don't care what order you get them out:

function asyncIterate(o,callback,timeout){
  var kv=[], i=0;
  for (var k in o) if (o.hasOwnProperty(k)) kv.push([k,o[k]);
  var iterator = function(){
    callback(kv[i][0],kv[i][1]);
    if (++i < kv.length) setTimeout(iterator,timeout); 
  }
  setTimeout(iterator,timeout);
}
asyncIterate(o,function(k,v){
  console.log(k+'='+v);
},2000);

JavaScript does not have something like Lua's next() function that allows you to find the next key/value pair after a given one.

If you do care about the order of the entries, then you need to store your original key/value pairs in an array, not an object.

Community
  • 1
  • 1
Phrogz
  • 296,393
  • 112
  • 651
  • 745
  • So you have to create an array to do it? Is there no way without creating an array? – Aaron Yodaiken Dec 27 '11 at 17:31
  • @luxun -- JS object properties are NOT ordered. You can keep just the order (not the values) in an array. In that case you'll have two data structures, an array for the order of the properties and an object to hold the values of the properties. – Larry K Dec 27 '11 at 17:38
  • @luxun If you could rely on the order of iteration (which some browsers guarantee) you could do it via a horrible mechanism of storing the last key seen and then (on each callback) iterating the object until you see that key. But not only is this horrifically inefficient, it's not guaranteed to work per the spec. – Phrogz Dec 27 '11 at 17:48
  • No, I'm not talking about a set order, I'm talking about an undefined order but iterating. In your code above, you make an array out of the object to iterate through. – Aaron Yodaiken Dec 27 '11 at 18:31
  • Also, I can't change the contents of `stupidf` in the context of my code because it's actually an HTTP protocol I don't have control over. – Aaron Yodaiken Dec 27 '11 at 18:33