10

我有一个类,ChatRoom它只能在它接收到一个长时间运行的 HTTP 请求后呈现(它可能需要 1 秒或 30 秒)。所以我需要延迟渲染直到ChatRoom.json不为空。

在下面的代码中,我使用了闭包库的goog.async.ConditionalDelay. 它可以工作,但是有没有更好的方法(也许不需要闭包库)来做到这一点?

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

这将每半秒检查一次。

现场演示:http: //jsfiddle.net/kBgTx/

于 2011-09-26T18:22:16.350 回答
1

你也可以使用 lodash 的 debouncer 来实现这一点。

import _debounce from 'lodash/debounce';

const wait = (() => {
    if ( chatroom.json ) {
        chatroom.render();
    } else {
      _debounce(wait, 500)();
    }
})();

于 2019-04-15T15:18:19.390 回答
-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');
}

我有一个检查函数,它定期运行一次,循环运行两次:

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 回答