# waitFun.mjs

    import get from 'lodash/get'
    import genPm from './genPm.mjs'
    import isfun from './isfun.mjs'
    import ispint from './ispint.mjs'

    /**
     * 等待f函數回傳true
     * 原始名稱為waitFunction，但與nodejs或travis-ci有名稱衝突，故才改為waitFun
     *
     * Unit Test: {@link https://github.com/yuda-lyu/wsemi/blob/master/test/waitFun.test.mjs Github}
     * @memberOf wsemi
     * @param {Function} f 輸入判斷用函數
     * @param {Object} opt 輸入設定物件，預設{}
     * @param {Integer} [opt.attemptNum=200] 輸入最大嘗試次數，為正整數，預設200
     * @param {Integer} [opt.timeInterval=1000] 輸入嘗試時間週期，為正整數，單位為ms，預設1000
     * @returns {Promise} 回傳Promise，resolve為空代表f函數回傳true或超過最大嘗試次數，reject為錯誤訊息
     * @example
     *
     * async function topAsync() {
     *
     *     function test1() {
     *         return new Promise((resolve, reject) => {
     *             let ms = []
     *
     *             let i = 0
     *             waitFun(function() {
     *                 i++
     *                 console.log('waiting: ' + i)
     *                 ms.push('waiting: ' + i)
     *                 return i >= 2
     *             })
     *                 .then(function() {
     *                     console.log('t1 then')
     *                     ms.push('t1 then')
     *                 })
     *
     *             setTimeout(function() {
     *                 resolve(ms)
     *             }, 1100)
     *
     *         })
     *     }
     *     console.log('test1')
     *     let r1 = await test1()
     *     console.log(JSON.stringify(r1))
     *     // test1
     *     // waiting: 1
     *     // waiting: 2
     *     // t1 then
     *     // ["waiting: 1","waiting: 2","t1 then"]
     *
     * }
     * topAsync().catch(() => {})
     *
     */
    function waitFun(f, opt = {}) {

        //pm
        let pm = genPm()

        //check
        if (!isfun(f)) {
            pm.reject('waitfunction需輸入函數f')
            return pm
        }

        //immediate call
        if (f() === true) {
            pm.resolve()
            return pm
        }

        //attemptNum
        let attemptNum = get(opt, 'attemptNum', null)
        if (!ispint(attemptNum)) {
            attemptNum = 200
        }

        //timeInterval
        let timeInterval = get(opt, 'timeInterval', null)
        if (!ispint(timeInterval)) {
            timeInterval = 1000
        }

        //setInterval
        let n = 0
        let t = setInterval(function() {
            n += 1
            //console.log('waitFun: ', n)

            if (f() === true) {
                //console.log('resolve', n)
                clearInterval(t)
                pm.resolve()
            }
            if (n > attemptNum) {
                //console.log('reject', n, attemptNum)
                clearInterval(t)
                pm.resolve() //已超過最大次數
            }

        }, timeInterval)

        return pm
    }

    export default waitFun