{"size": 2165, "ext": "js", "max_stars_repo_path": "lib/whileMax.js", "max_stars_repo_name": "olono/await-the", "max_stars_repo_stars_event_min_datetime": "2018-08-24T20:28:52.000Z", "max_stars_repo_stars_event_max_datetime": "2020-07-06T00:24:33.000Z", "max_issues_repo_path": "lib/whileMax.js", "max_issues_repo_name": "olono/await-the", "max_issues_repo_issues_event_min_datetime": "2019-11-05T18:45:24.000Z", "max_issues_repo_issues_event_max_datetime": "2020-11-02T19:10:15.000Z", "max_forks_repo_path": "lib/whileMax.js", "max_forks_repo_name": "olono/await-the", "max_forks_repo_forks_event_min_datetime": null, "max_forks_repo_forks_event_max_datetime": null}
{"max_stars_count": 5, "max_issues_count": 2, "max_forks_count": null, "avg_line_length": 36.0833333333, "max_line_length": 116, "alphanum_fraction": 0.6697459584}
/**
 * @file Given a condition, maximum amount of loop iterations to do, and function, continuously call the promisified
 * version of that function sequentially and return the result once the exiting condition is met or the loop
 * count has been exhausted.
 * @copyright Copyright (c) 2020 Olono, Inc.
 */

'use strict';

const awaitWhile = require('../lib/while');

/**
 * Given a condition, maximum amount of loop iterations to do, and function, continuously call the promisified
 * version of that function sequentially and return the result once the exiting condition is met or the loop
 * count has been exhausted.
 *
 * The `condition` can access either the parent scoped variables or the results of `fn` which are passed in
 * as the only parameter.
 *
 * @module whileMax
 * @example
 * const the = require('await-the');
 * let sum = 0;
 * const max = 2;
 * const condition = previousResult => sum < 10;
 * const asyncFn = x => {
 *     sum += x;
 *     return sum * 10;
 * }
 * const result = await the.whileMax(condition, max, asyncFn, 2);
 * // is cut off by hitting the max loops possible
 * // sum === 4
 * // result === 40
 *
 * @param {Function} condition The condition to continue looping.
 * @param {Number} maxIterations The maximum amount of loop iterations to be done.
 * @param {Function|Array} fn The function to be resolved (or rejected) every loop.
 * @param {...*} args Variadic arguments to send to the function.
 * @returns {*} The thrown error or the result.
 */
module.exports = async (condition, maxIterations, fn, ...args) => {
    let count = 0;
    if (isNaN(maxIterations)) {
        throw new Error(`The max iterations is not a number: ${maxIterations}`);
    } else if (maxIterations < 1) {
        throw new Error(`The whileMax function was started with an invalid max iterations: ${maxIterations}`);
    } else if (!(await condition())) {
        return;
    }
    const conditionWithMax = async previousResult => {
        count++;
        if (count > maxIterations) {
            return false;
        }
        return await condition(previousResult);
    };

    return await awaitWhile(conditionWithMax, fn, ...args);
};
