一尘不染

对RequireJS可用资源的投票

node.js

因此,我使用RequireJS和Socket.io编写了一个应用程序,该应用程序检查socket.io资源是否可用,然后在连接时引导该应用程序。万一socket.io暂时关闭,我想对资源进行几次requireJS轮询,直到可用为止,然后继续初始化应用程序。

不幸的是(或者幸运的是?)似乎有某种缓存机制要求require为未加载的脚本注册脚本错误,因此,如果您在错误回调中执行setTimeout重试socketio
require函数,则require将继续即使资源可用也会引发错误。

这是疏忽还是有理由保留此错误?更重要的是,是否有一种解决方法可以允许要求重试?

这是我一直在尝试的示例:

function initialize() {
  require(['socketio', function(io) {
    io.connect('http://localhost');
    app._bootstrap();
  }, function(err) {
    console.log(err);
    setTimeout(initialize, 10000);
  });
}

阅读 251

收藏
2020-07-07

共1个答案

一尘不染

我知道这是一个古老的问题,但这让我很感兴趣,所以我调查了一下…

您需要调用一个require.undef方法,以告知RequireJS不要缓存加载的先前失败状态。另请参见errbacks示例。

然后,您可以再次使用null回调再次调用require。原始回调仍将被调用-无需递归。像这样:

function requireWithRetry(libname, cb, retryInterval, retryLimit) {
    // defaults
    retryInterval = retryInterval || 10000;
    retryLimit = retryLimit || 10;

    var retryCount = 0;
    var retryOnError = function(err) {
        var failedId = err.requireModules && err.requireModules[0];
        if (retryCount < retryLimit && failedId === libname) {
            // this is what tells RequireJS not to cache the previous failure status
            require.undef(failedId);

            retryCount++;
            console.log('retry ' + retryCount + ' of ' + retryLimit)

            setTimeout(function(){
                // No actual callback here. The original callback will get invoked.
                require([libname], null, retryOnError);
            }, retryInterval);

        } else {
            console.log('gave up', err)
        }
    }

    // initial require of the lib, using the supplied callback plus our custom
    // error callback defined above
    require([libname], cb, retryOnError);
}

requireWithRetry('socketio', function(io) {
    io.connect('http://localhost');
    app._bootstrap();
});
2020-07-07