-
Notifications
You must be signed in to change notification settings - Fork 1
/
eachtick.js
51 lines (49 loc) · 1.36 KB
/
eachtick.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
/**
* . .---. .
* | | o |
* .-. .-. .-.|--. | . .-.|.-.
* (.-'( )( | | | | ( |-.'
* `--'`-'`-`-'' `-'-' `-`-'' `-
*
* -----------------------------------
* Non-blocking asynchronous iteration
* for Node.js and the browser.
* -----------------------------------
*
*/
'use strict';
if (typeof require !== 'undefined') require('setimmediate');
/**
* Perform iterations on each tick
*
* @param obj
* Object or array to be iterated over
* @param iterator
* Iterator to call each iteration
* @param complete
* Iteration is complete, there was
* an error, or stop was called
*/
function eachtick(obj, iterator, complete){
var keys = Object.keys(obj);
(function iterate(keys){
setImmediate(function(){
if (!keys[0]) return complete ? complete() : false;
// Return the key / value pair, wait for next callback
iterator(keys[0], obj[keys[0]], function next(err, stop){
// Stop iterating on error, stop instruction, or completion
if (err || stop || keys.length === 1) return complete ? complete(err, stop) : false;
// Grab a slice to go. Pepperoni please.
return ((keys = keys.slice(1)).length && iterate(keys));
});
});
})(keys);
}
/**
*
* Node.js exports
*
*/
if (typeof module !== 'undefined') {
module.exports = eachtick;
}