【问题标题】:Patterns or techniques for ensuring script availability?确保脚本可用性的模式或技术?
【发布时间】:2011-03-17 17:16:26
【问题描述】:

随着我一直从事的项目越来越多,当其他代码尝试访问页面上的所有脚本时,页面上的所有脚本都不可用的情况越来越频繁。虽然这种情况最常发生在代码更新后(例如未缓存),但我在测试中越来越多地出现这种情况,但以前从未发生过。

我已经部分解决了这个问题,方法是使用一个函数等待模块可用(请参阅this question),这主要解决了这个问题,但我对实现并不完全兴奋,我寻找更具产业实力的格局来应对。这些是我想出的可能的解决方案:

1) 按需加载脚本类似ensure - 不理想。需要在每个脚本中包含实际的脚本名称依赖信息,而不仅仅是模块/对象名称,以执行此操作。在使用资源之前仍需采取一些措施以确保其可用。

2) 管理脚本加载顺序。如果这甚至可以工作(例如,我不认为简单地将脚本 A 放在脚本 B 之前就可以保证它可用,因为它们可以同时加载),这将是一个痛苦,因为你不知道依赖关系直到你已经加载了依赖它的东西。在一个拥有大量使用不同资源的页面的网站上进行设置需要做大量工作(而且我无意在每个页面上加载网站上到处使用的所有内容)。

3) 等待所有内容加载到给定页面上,然后再允许用户交互。由于显而易见的原因,远非理想。仍然没有解决初始化代码中发生的依赖关系。

4) 扩展我目前的解决方案。目前的工作方式是(这是伪代码,但基本的逻辑过程):

// Depends on Module2
Module1 = (function () {
   self = {};
   // function requires dependency
   // waitFor waits until global named 'dependency' is available then calls callback
   self.initialized=false; 
   self.init = function() {
       waitFor('Module2', function() {
           self.intialized=true;
       });
   }
  // waitForInitialization sets a callback when self.initialized=true
   self.func = self.waitForInitialization(func() {
           Module2.doStuff();
       });
   }
   //UI-initiated function requires dependency
   self.uiFunc = function() {
       if (!self.initialized) {
          showPleaseWaitDialog();
          self.waitForInitialization(function() {
              dismissPleaseWaitDialog();
              self.uiFuncImpl);
       } else {
          self.uiFuncImpl();
       }
   }
   self.uiFuncImpl= function() { 
       Module2.doStuff();
   }
} ());

我可以想办法创建一个比我上面的代码更透明地处理依赖问题的原型,并且如果我必须这样做,我完全打算这样做,但这真的是最好的解决方案吗?别人做什么?什么是最佳做法?

【问题讨论】:

  • 渐进式增强和在 document.ready 上调用您的 javascript 函数/对象有什么问题?
  • document.ready 不保证加载包含,只是加载 DOM。
  • @Jamietre 你会发现 jQuery document.ready 确实保证了 javascript 从头部包含的内容被加载。
  • 我正在使用 jQuery,它是第一个包含,我可以轻松地复制它。我可能做错了什么?某些页面上很容易包含 20 个包含,是否有任何可能的原因导致特定于浏览器的行为可能导致此功能不起作用?所有包含的内容也都在脑海中。有些是动态的(例如资源加载器)。
  • 理论上你应该能够定义你的模块/类并使用$(document).ready(function() { module1.init(); module2.init(); ... });来处理这个问题。也许看看 head.js 或 require.js。

标签: javascript dependencies design-patterns


【解决方案1】:

2) 脚本加载顺序 - 脚本将始终按照它们在 DOM 中放置的顺序执行,因此虽然它们可能同时加载,但它们将以有序的方式执行(在我从事的大型项目中面临同样的问题) .

?) 如果脚本加载顺序对您来说不是一个理想的解决方案,您可以查看Promise 模型。

??) 如果 Promises 和 Load Order 对您不起作用,您可以监听每个模块在初始化时可以触发的命名空间事件,这样,如果对象存在,则可以使用它,如果不存在,则可以使用它的初始化被倾听。

【讨论】:

  • 很高兴知道加载顺序得到尊重。这很困难,因为我必须将依赖信息添加到我正在使用的资源管理过程中并让它处理它。现在事情往往完全倒退(因为模块是由需要依赖的模块添加的)。但因为它实际上会起作用——这可能是最好的解决方案。我现在基本上在使用 Promise(除了专门请求加载资源,我等待它出现)。没有考虑事件模型,听起来很有趣,比我现在的方式更好。
  • 我注意到,在我发布有关 Promises 的文章后,它们似乎很快就流行起来了。在我看来,事件模型并不理想,但它很有效,可以让你的模块对它不需要知道的事情保持无知。每个对象都必须知道它的依赖关系是什么。
  • 它可以工作,我只是不喜欢让每个方法在它有依赖关系时都做其他事情。正如我在原始问题末尾提到的那样,我认为我可以开发一些东西来以某种方式封装它,但听起来像是工作。对于我的情况,让代码从底部优先排列脚本可能会更容易,如果这真的可以解决问题的话。
  • 我使用了一个有扩展方法的基对象,其他对象将自己添加到基类中注册自己的命名空间,基对象根据这些命名空间添加必要的代码来触发事件,并抓取依赖来自对象的数据来处理侦听器。它还允许我使用比基本 js 允许的更经典的继承风格。
  • 基本上js等价于类ClassName扩展OtherClass,其中OtherClass扩展BaseClass。
猜你喜欢
  • 2010-11-29
  • 1970-01-01
  • 2020-10-14
  • 1970-01-01
  • 2017-09-02
  • 2014-12-25
  • 1970-01-01
  • 1970-01-01
  • 2018-07-27
相关资源
最近更新 更多