Asynchronously delay JS until a condition is met

后端 未结 3 1213
太阳男子
太阳男子 2021-02-06 01:45

I have a class, ChatRoom, that can only render after it receives a long-running HTTP request (it could take 1 second or 30 seconds). So I need to delay rendering un

相关标签:
3条回答
  • 2021-02-06 01:50

    Consider this:

    (function wait() {
        if ( chatroom.json ) {
            chatroom.render();
        } else {
            setTimeout( wait, 500 );
        }
    })();
    

    This will check every half second.

    Live demo: http://jsfiddle.net/kBgTx/

    0 讨论(0)
  • 2021-02-06 02:03

    You could also achieve this using lodash's debouncer with recursion.

    import _debounce from 'lodash/debounce';
    
    const wait = (() => {
        if ( chatroom.json ) {
            chatroom.render();
        } else {
          _debounce(wait, 500)();
        }
    })();

    0 讨论(0)
  • 2021-02-06 02:09

    The answer I came up with is like this:

    var count = 0;
    // Number of functions that need to run. This can be dynamically generated
    // In this case I call check(data, cb) a total of 3 times
    var functionNum = 3; 
    function toCallAfter(){
        console.log('I am a delayed function');
    }
    

    I had this for a check function that ran once regularly and twice in a loop:

    check(data, function(err){ // check is my asynchronous function to check data integrity
        if (err){
            return cb(null, { // cb() is the return function for the containing function
                errCode: 'MISSINGINFO',
                statusCode: 403,
                message : 'All mandatory fields must be filled in'
            });
        } // This part here is an implicit else
        count++; // Increment count each time required functions complete to
                 // keep track of how many function have completed
        if (count === functionNum) {
            return anon();
        }
        return;
    });
    // Run twice more in a loop
    for(var i = 0; i < 2; i++) {
        check(data, function(err) { // calls check again in a loop
            if (err){
                return cb(null, {
                    errCode: 'MISSINGINFO',
                    statusCode: 403,
                    message : 'All mandatory fields must be filled in'
                });
            }
            count++;
            if (count === functionNum) {
                return toCallAfter();
            }
            return;
        });
    }
    

    Lastly, I'd like to point out a significant performance fault in the alternate (and extraordinarily common) answer:

    (function wait() {
        if ( chatroom.json ) {
            chatroom.render();
        } else {
            setTimeout( wait, 500 );
        }
    })();
    

    In this case, you are essentially holding the browser or server (If using node.js) hostage for 500 milliseconds for every check which is an incredibly long time for a computer. Meaning a huge performance hit. My solution of directly keeping track of the required completed functions is free from time restraints and will run instantly as soon as all functions complete.

    0 讨论(0)
提交回复
热议问题