diff --git a/source/Ox/js/Async.js b/source/Ox/js/Async.js index 94ddb258..36ee4ec2 100644 --- a/source/Ox/js/Async.js +++ b/source/Ox/js/Async.js @@ -1,3 +1,5 @@ +'use strict'; + (function() { function asyncMap(forEach, col, iterator, that, callback) { @@ -32,7 +34,7 @@ (col, iterator[, that], callback[, ms]) -> undefined @*/ Ox.nonblockingForEach = function(col, iterator, that, callback, ms) { - var i, keys, last = Ox.last(arguments), n, time, type = Ox.typeOf(col); + var i = 0, keys, last = Ox.last(arguments), n, time, type = Ox.typeOf(col); callback = Ox.isFunction(last) ? last : arguments[arguments.length - 2]; col = type == 'array' || type == 'object' ? col : Ox.toArray(col); keys = type == 'object' ? Object.keys(col) : Ox.range(col.length); @@ -44,16 +46,25 @@ time = +new Date(); iterate(); function iterate() { - keys[i] in col && iterator.call(that, col[keys[i]], keys[i], col); - if (++i < n) { - if (+new Date() < time + ms) { - iterate(); - } else { - setTimeout(function() { - time = +new Date(); - iterate(); - }); + Ox.forEach(keys.slice(i), function(key) { + if (key in col) { + try { + iterator.call(that, col[key], key, col); + } catch(e) { + if (e === Ox.BreakError) { + i = n; + } + throw e; + } } + i++; + +new Date() >= time + ms && Ox.break(); + }); + if (i < n) { + setTimeout(function() { + time = +new Date(); + iterate(); + }, 1); } else { callback(); } @@ -62,28 +73,38 @@ /*@ Ox.nonblockingMap Non-blocking map with synchronous iterator - (col, iterator[, that], callback) -> undefined + (col, iterator[, that]) -> undefined col Collection iterator Iterator function that The iterator's this binding callback Callback function @*/ - Ox.nonblockingMap = function() { - asyncMap.apply(null, [Ox.nonblockingForEach].concat(Ox.toArray(arguments))); + Ox.nonblockingMap = function(col, iterator, that, callback, ms) { + var last = Ox.last(arguments), + type = Ox.typeOf(col), + results = type == 'object' ? {} : []; + callback = Ox.isFunction(last) ? last : arguments[arguments.length - 2]; + that = arguments.length == 5 || ( + arguments.length == 4 && Ox.isFunction(last) + ) ? that : null; + Ox.nonblockingForEach(col, function(val, key, obj) { + results[key] = iterator.call(that, val, key, obj); + }, function() { + callback(type == 'string' ? results.join('') : results); + }, ms); }; /*@