Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

"Async" loop over an object in javascript

Normally, we can do loops for both arrays and objects to iterate over the properties/values. But loops are blocking. However, timeouts can be used to simulate an async loop. i managed to do it for an array.

//do stuff

(function asyncLoop(i){

    //do stuff in the current iteration

    if(++i < array.length){
        setTimeout(function(){asyncLoop(i);}, 1);
    } else {
        callback();
    }
}(0));

//do stuff immediately after, while looping

but this model only works while looping in an array, where there is a limiter - the i that gets passed around. is there a way to do this over an object? let's just say that the object has 50k keys to iterate through, making it unreasonably long.

i already know of this setImmediate (afaik, only newer IE) and WebWorkers(not yet in IE), but i just want to know if it's possible to just use the same strategy on an object.

like image 948
Joseph Avatar asked Apr 18 '12 10:04

Joseph


People also ask

Can you loop through an object JavaScript?

Object. key(). It returns the values of all properties in the object as an array. You can then loop through the values array by using any of the array looping methods.

Is JavaScript for loop asynchronous?

For loops. Combining async with a for (or a for...of ) loop is possibly the most straightforward option when performing asynchronous operations over array elements. Using await inside a for loop will cause the code to stop and wait for the asynchronous operation to complete before continuing.

How do I use async await inside for loop?

You need to place the loop in an async function, then you can use await and the loop stops the iteration until the promise we're awaiting resolves. You could also use while or do.. while or for loops too with this same structure.


1 Answers

There is no async-capable iterator of properties because there's no way to save the state of where you are in the iterator other than the for (key in obj) loop and you already know that isn't async-compatible.

So, just collect all the keys of the object into an array and use the same mechanism you already have to iterate over the array of keys. Arrays have the advantage that they do have a way to save the state of where you are in the iteration by just keeping track of the array index.

One can get all the keys, either with the Object.keys(obj) ES5 method (via built-in methods or ES5 shim if needed) or you can collect them yourself if you aren't otherwise using ES5 shims:

var keys = [];
for (var i in obj) {
    if (obj.hasOwnProperty(i)) {
        keys.push(i);
    }
}
like image 116
jfriend00 Avatar answered Sep 19 '22 19:09

jfriend00