【问题标题】:nodejs, cascade calls to asynchronous function until condition occursnodejs,级联调用异步函数,直到条件发生
【发布时间】:2021-07-25 20:55:22
【问题描述】:

我需要多次调用异步函数(这里是强制电机速度),直到达到最大速度。

但我不知道如何在没有预定义呼叫次数的情况下编写“多次呼叫”。 这是我的代码的基础。

/* drive motor
        from initialSpeedPercent
        to finalSpeedPercent
        step by step with delay
    */
var initialSpeedPercent = 0;
var finalSpeedPercent = 80;
var duration = 2000;    // in millisecond
var accelerationStep = 5;

var stepSpeed = (finalSpeedPercent - initialSpeedPercent) / (accelerationStep - 1);
var stepDuration = duration / (accelerationStep - 1);


function setMotorSpeed( percentOfSpeed, funcWhenCompleted) {
    // send consign to motor then return
    console.log( `motorspeed set to ${percentOfSpeed}`);
    let err = undefined;    // depending of motor behavior
    if (err) {
        funcWhenCompleted( { cmd: 'setMotorSpeed', err: err }, undefined );
    }
    else {
        funcWhenCompleted( undefined, { cmd: 'setMotorSpeed', newSpeed: percentOfSpeed } );
    }
}


const promiseSpeed = new Promise( function ( resolve, reject ) {
    
    initialSpeedPercent += stepSpeed;
    setMotorSpeed( initialSpeedPercent, function (err, result) {
        if (err) {
            reject( err);
        } else {
            // resolve after step duration
            setTimeout( () => {
                resolve( result );
            }, stepDuration );
        }
    } );
} );

promiseSpeed
    .then( ( result ) => {
        console.log( 'promiseSpeed success:', result );
        
        ... how to call in cascade.... until result.newSpeed >= finalSpeedPercent ?
        
        promiseSpeed
            .then( ( result ) => {
                console.log( 'promiseSpeed success:', result );
            } );
    } )
    .catch( ( error ) => {
        console.log( 'promiseSpeed error:', error );
    } )
    .finally( () => {
        console.log('promiseSpeed() is done!');
    } );

怎么做?

【问题讨论】:

    标签: node.js cascade


    【解决方案1】:

    我找到了这个解决方案。但我想有一种更简单的方法可以做到这一点。 如果内部调用过多,如何避免危险的堆栈溢出?

    /*  _testCascade.js
    
        - Drive motor speed principle, step by step
        */
        
    Date.prototype.yyyymmddhhmmsslll = function() {
        var yyyy = this.getFullYear();
        var mm = this.getMonth() < 9 ? "0" + (this.getMonth() + 1) : (this.getMonth() + 1); // getMonth() is zero-based
        var dd  = this.getDate() < 10 ? "0" + this.getDate() : this.getDate();
        var hh = this.getHours() < 10 ? "0" + this.getHours() : this.getHours();
        var min = this.getMinutes() < 10 ? "0" + this.getMinutes() : this.getMinutes();
        var ss = this.getSeconds() < 10 ? "0" + this.getSeconds() : this.getSeconds();
        var lll = this.getMilliseconds() < 10 ? "00" + this.getMilliseconds() : 
            this.getMilliseconds() < 100 ? "0" + this.getMilliseconds() :
            this.getMilliseconds();
        return yyyy + '-' + mm + '-' + dd + ' ' + hh + ':' + min + ':' + ss + '.' + lll;
        };
        
    /*  @params: { fromSpeed: -50, stepSpeed: +10, toSpeed: -12 }
            speed(s) in percent, from -100 to +100
        */
    function driveMotor( params) {
        const funcName = "driveMotor";
        // console.log( `${new Date()} > ${funcName} > enter with params: ${JSON.stringify(params)}...`);
        return new Promise((successCallback,failureCallback) => {   
            
            let objective = params.fromSpeed + params.stepSpeed;
            // TIMEOUT simulate asynchronous command of speed
            setTimeout( function() {
                const funcName = "asyncDriveMotor";
                
                // console.log( `${new Date()} > ${funcName} > command executed with objective: ${objective}...`);
                
                if (Math.random() > .2) {
                // if (true) {
                    // console.log( `${new Date()} > ${funcName} > success with objective: ${objective}...`);
                    let success = params;
                    success.reachedSpeed = objective;
                    successCallback( { err: undefined, success: success } );
                } else {
                    // console.log( `${new Date()} > ${funcName} > Promise FAILS with objective: ${objective}...`);
                    failureCallback( { err: true, success: undefined} );
                }
            }, 100);
        })
    }
    
    function progressiveDriveMotorSpeed( params) {
        
        if (params.stepSpeed == 0) {
            return;
        }
        if (params.fromSpeed < -100
            || params.fromSpeed > +100) return;
        if (params.toSpeed < -100
            || params.toSpeed > +100) return;
        
        let promise = driveMotor( params );
        
        promise.then( function(result) {
            const funcName = "driveMotor.then";
            
                let stop = false;
                
                console.log( `${new Date()} > ${funcName} > result: ${JSON.stringify(result)} `);
                if (result.err) {
                    console.log( `${new Date()} > ${funcName} > err: ${result.err}...stop required`);
                    stop = true;
                    
                } else {
                    // console.log( `${new Date()} > ${funcName} > success...`);
                    
                    if (result.success.stepSpeed > 0) {
                        if (result.success.reachedSpeed >= result.success.toSpeed) {
                         stop = true;
                        }
                    } 
                    
                    if (result.success.stepSpeed < 0) {
                        if (result.success.reachedSpeed <= result.success.toSpeed) {
                            stop = true;
                        }
                    }
                    
                    // console.log( `${new Date()} > ${funcName} > success 2...stop: ${stop}`);
                    if (stop == false) {
                        params.fromSpeed = result.success.reachedSpeed;
                        if ( (params.fromSpeed + params.stepSpeed) > params.toSpeed) {
                            params.fromSpeed = params.toSpeed - params.stepSpeed;
                            console.log( `${new Date()} > ${funcName} > adjust in order to reach exactly...params.fromSpeed: ${params.fromSpeed}`);
                        }
                        // recall
                        progressiveDriveMotorSpeed( params);
                    }
                }
            
        })
        .catch( function( result) {
            const funcName = "catch";
            if (result.err) {
                console.log( `${new Date()} > ${funcName} > FAILURE...result: ${JSON.stringify(result)} with params: ${JSON.stringify( params)} `);
            } else {
                console.log( `${new Date()} > ${funcName} > COMPLETED...result: ${JSON.stringify(result)} with params: ${JSON.stringify( params)}`);
            }
        }); 
    }
    
    /* tests:   
        progressiveDriveMotorSpeed( { fromSpeed: 0, stepSpeed: 10, toSpeed: 50 } );
        progressiveDriveMotorSpeed( { fromSpeed: 0, stepSpeed: 10, toSpeed: 48 } );
        progressiveDriveMotorSpeed( { fromSpeed: 50, stepSpeed: -10, toSpeed: 0 } );
        progressiveDriveMotorSpeed( { fromSpeed: -50, stepSpeed: +10, toSpeed: -12 } );
        */
    progressiveDriveMotorSpeed( { fromSpeed: -50, stepSpeed: +10, toSpeed: -12 });
    

    【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-05-31
    • 2022-01-26
    • 2020-08-07
    • 1970-01-01
    • 1970-01-01
    • 2020-03-04
    • 1970-01-01
    相关资源
    最近更新 更多