Skip to content

Instantly share code, notes, and snippets.

@co3moz
Last active April 5, 2016 16:34
Show Gist options
  • Save co3moz/0fc4694c84da16db34c4 to your computer and use it in GitHub Desktop.
Save co3moz/0fc4694c84da16db34c4 to your computer and use it in GitHub Desktop.
Async Array Iterator
Array.prototype.iterate = function (cb, done, timeout) {
((timeout != undefined) || (typeof timeout == "object") || (timeout = 5000));
var total = this.length;
var result = [];
if (total == 0) {
return done(null, result);
}
var sent = false;
this.forEach(function (e, i) {
setTimeout(function () {
cb(e, function (data) {
if (data instanceof Error) {
if (!sent) {
done(data, null);
sent = true;
}
} else {
result[i] = data;
if (--total == 0 && !sent) {
done(null, result);
sent = true;
}
}
})
});
});
if (timeout != null) {
setTimeout(function () {
if (total != 0 && !sent) {
done(Error("timeout"), null);
sent = true;
}
}, timeout);
}
};
@co3moz
Copy link
Author

co3moz commented Apr 4, 2016

example

[1, 2, 3, 4].iterate(function(obj, done) {
  console.log(obj, obj * 2);
  done(obj * 2);
}, function(err, result) {
  if(err) {
    return console.error(err);
  }
  console.log(result);
});
1 2
2 4
3 6
4 8
[2, 4, 6, 8]

@co3moz
Copy link
Author

co3moz commented Apr 4, 2016

another example

[1, 2, 3, 4].iterate(function(obj, done) {
  setTimeout(function() {
    console.log(obj + " finished");
    done(obj * 1000);
  }, 1000 * obj);
}, function(err, result) {
  if(err) {
    return console.error(err);
  }
  console.log(result);
});
1 finished
2 finished
3 finished
4 finished
[1000, 2000, 3000, 4000]

result doesn't change result index if data came with different order

[1, 2, 3, 4].iterate(function(obj, done) {
  setTimeout(function() {
    console.log(obj + " finished");
    done(obj * 1000);
  }, 4000 - 1000 * obj);
}, function(err, result) {
  if(err) {
    return console.error(err);
  }
  console.log(result);
});
4 finished
3 finished
2 finished
1 finished
[1000, 2000, 3000, 4000]

@co3moz
Copy link
Author

co3moz commented Apr 4, 2016

timeout example

[1, 2, 3].iterate(function() { /* missing done or it isn't finished over the time */}, function(err, results) { 
  console.log(err, results); // err says its timeout
});
[1].iterate(function(i, done) {
  setTimeout(function() {
    done(i);
  }, 10000);
}, function(err, results) {
  if(err) // again err is true because it timeout default is 5000 (5sec) and done is calling after 10second..
});
// to prevent this you can use third parameter
[1].iterate(function(i, done) {
  setTimeout(function() {
    done(i);
  }, 10000);
}, function(err, results) {
 // no problem
}, 15000);

// for disable timeout use null 
[1].iterate(function(i, done) {
  setTimeout(function() {
    done(i);
  }, 10000);
}, function(err, results) {
 // no problem
}, null);

@co3moz
Copy link
Author

co3moz commented Apr 4, 2016

error example

[1, 2, 3].iterate(function(i, done) {
  if(i == 2) {
    done(Error("something bad happened!"));
  } else {
    done(i);
  }
}, function(err, results) {
  console.log(err, results); // err = something bad.., results = empty
})

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment