【问题标题】:Poll for resource available with RequireJS使用 RequireJS 轮询可用资源
【发布时间】:2013-07-10 01:28:46
【问题描述】:

所以我正在使用 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);
  });
}

【问题讨论】:

  • 认为这更像是一个概念性问题,但我已经快速更新了帖子。
  • Socketio 映射到我的 require.config 中的正确位置。我的脚本可用的原因是该应用程序在 Drupal 中运行(在 apache 上),但依赖于 node/socket.io 服务,我相信它有时会失败。这不是必须的,但我认为如果应用程序在节点服务器恢复后立即在浏览器中启动会很酷(假设用户访问页面时它已关闭)。

标签: javascript node.js requirejs amd socket.io


【解决方案1】:

我知道这是一个老问题,但我很感兴趣,所以我研究了一下......

你需要调用一个require.undef method 来告诉RequireJS 不要缓存之前加载的失败状态。另请参阅 errbacks 示例。

然后您可以简单地再次调用 require 并使用 null 回调。原始回调仍将被调用——不需要递归。像这样的:

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

【讨论】:

  • 这太棒了,正是我想要的!谢谢。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-08-29
  • 2011-03-27
  • 1970-01-01
  • 2012-04-05
  • 2016-02-01
相关资源
最近更新 更多