Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Asynchronously delay JS until a condition is met

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 until ChatRoom.json is not null.

In the code below, I'm using Closure Library's goog.async.ConditionalDelay. It works, but is there a better way (maybe without needing Closure Library) to do this?

ChatRoom.prototype.json = null; // received after a long-running HTTP request.

ChatRoom.prototype.render = function() {
    var thisChatRoom = this;

    function onReady() {
        console.log("Received JSON", thisChatRoom.json);
        // Do rendering...
    }

    function onFailure() {
        alert('Sorry, an error occurred. The chat room couldn\'t open');
    }

    function isReady() {
        if (thisChatRoom.json != null) {
            return true;
        }
        console.log("Waiting for chat room JSON...");
        return false;
    }

    // If there is a JSON request in progress, wait until it completes.
    if (isReady()) {
        onReady();
    } else {
        var delay = new goog.async.ConditionalDelay(isReady);
        delay.onSuccess = onReady;
        delay.onFailure = onFailure;
        delay.start(500, 5000);
    }
}

Note that "while (json == null) { }" isn't possible because that would be synchronous (blocking all other JS execution).

like image 720
Amy B Avatar asked Sep 26 '11 18:09

Amy B


People also ask

How do you wait for an async function to finish?

Inside an async function, you can use the await keyword before a call to a function that returns a promise. This makes the code wait at that point until the promise is settled, at which point the fulfilled value of the promise is treated as a return value, or the rejected value is thrown.

Does JavaScript wait for function to finish before continuing?

By default, the execution of JavaScript code is asynchronous. It represents that JavaScript does not wait for a function to complete before starting on the other parts of the code.

How do you wait for a while in JavaScript?

Create a Simple Delay Using setTimeout The standard way of creating a delay in JavaScript is to use its setTimeout method. For example: console. log("Hello"); setTimeout(() => { console.


2 Answers

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/

like image 197
Šime Vidas Avatar answered Oct 08 '22 09:10

Šime Vidas


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)();
    }
})();
like image 25
Lewis James-Odwin Avatar answered Oct 08 '22 08:10

Lewis James-Odwin