Commit 2ef6bd5d authored by Tristan Cavelier's avatar Tristan Cavelier

jIO.util.range added

parent 3373d8d1
......@@ -480,3 +480,97 @@ function forEach(array, fn, thisArg) {
});
}
exports.util.forEach = forEach;
/**
* range(stop, callback): Promise
* range(start, stop[, step], callback): Promise
*
* It executes the provided `callback` once for each step between `start` and
* `stop`. If the `callback` returns a promise, then the function will wait
* for its fulfillment before executing the next iteration.
*
* `callback` is invoked with one argument:
*
* - the index of the step
*
* `start`, `stop` and `step` must be finite numbers. If `step` is not
* provided, then the default step will be `1`. If `start` and `step` are not
* provided, `start` will be `0` and `step` will be `1`.
*
* Inspired by `range()` from Python 3 built-in functions.
*
* range(10, function (index) {
* return notifyIndex(index);
* }).then(onDone, onError, onNotify);
*
* @param {Number} [start=0] The start index
* @param {Number} stop The stop index
* @param {Number} [step=1] One step
* @param {Function} callback Function to execute on each iteration.
* @param {Promise} A new promise with no fulfillment value.
*/
function range(start, stop, step, callback) {
var type_object, cancelled, current_promise;
type_object = arrayValuesToTypeDict([start, stop, step, callback]);
if (type_object["function"].length !== 1) {
throw new TypeError("range(): only one callback is needed");
}
start = type_object.number.length;
if (start < 1) {
throw new TypeError("range(): 1, 2 or 3 numbers are needed");
}
if (start > 3) {
throw new TypeError("range(): only 1, 2 or 3 numbers are needed");
}
callback = type_object["function"][0];
if (start === 1) {
start = 0;
stop = type_object.number[0];
step = 1;
}
if (start === 2) {
start = type_object.number[0];
stop = type_object.number[1];
step = 1;
}
if (start === 3) {
start = type_object.number[0];
stop = type_object.number[1];
step = type_object.number[2];
if (step === 0) {
throw new TypeError("range(): step must not be zero");
}
}
type_object = undefined;
current_promise = RSVP.resolve();
return new RSVP.Promise(function (done, fail, notify) {
var i = start, test;
function next() {
if (cancelled) {
fail(new Error("Cancelled"));
return;
}
test = step > 0 ? i < stop : i > stop;
if (test) {
current_promise = current_promise.then(callback.bind(null, i));
current_promise.then(next, fail, notify);
i += step;
return;
}
done();
}
next();
}, function () {
cancelled = true;
if (typeof current_promise.cancel === "function") {
current_promise.cancel();
}
});
}
exports.util.range = range;
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment