10

長時間実行される HTTP 要求を受信した後にのみレンダリングできるクラスがありChatRoomます (1 秒または 30 秒かかる場合があります)。したがってChatRoom.json、 null でなくなるまでレンダリングを遅らせる必要があります。

以下のコードでは、Closure Library のgoog.async.ConditionalDelay. それは機能しますが、これを行うためのより良い方法はありますか (おそらく Closure Library を必要とせずに)?

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);
    }
}

"while (json == null) { }" は同期的 (他のすべての JS 実行をブロックする) であるため、使用できないことに注意してください。

4

3 に答える 3

29

このことを考慮:

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

これにより、0.5 秒ごとにチェックされます。

ライブデモ: http://jsfiddle.net/kBgTx/

于 2011-09-26T18:22:16.350 に答える
-1

私が思いついた答えは次のようなものです:

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');
}

これは、定期的に1回、ループで2回実行されるチェック機能用にありました。

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;
    });
}

最後に、別の (そして非常に一般的な) 回答の重大なパフォーマンス障害を指摘したいと思います。

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

この場合、基本的に、ブラウザーまたはサーバー (node.js を使用している場合) をチェックごとに 500 ミリ秒間人質に取っていることになりますが、これはコンピューターにとって信じられないほど長い時間です。パフォーマンスに大きな打撃を与えることを意味します。必要な完了した機能を直接追跡する私のソリューションは、時間の制約がなく、すべての機能が完了するとすぐに実行されます。

于 2016-02-08T20:05:05.347 に答える