异步javascript准备功能

时间:2011-08-21 07:47:03

标签: javascript asynchronous

为了加速我的应用程序,我想在DOM准备好之前准备一些数据,然后在DOM准备就绪时使用这些数据。

这是怎么回事:

var data = function prepareData(){
  ...
}();

$(document).ready(function() {

   // use data to build page

}

如何准备数据供以后使用? 感谢

1 个答案:

答案 0 :(得分:3)

为了清楚起见,

你需要 在函数表达式周围使用括号(因为在你定义和调用函数但不使用返回值的类似情况下,没有它们会是语法错误)。此外,当您使用函数表达式时,您不希望为其命名。所以:

var data = (function(){
    ...
})();

或使用函数声明

var data = processData();
function processData() {
    ...
}

(为什么不使用带有函数表达式的名称?由于各种实现中的错误,尤其是IE9之前的Internet Explorer,will create two完全不相关的函数。)

但是,我不清楚你想要实现的目标。当浏览器到达script元素时,它会转到JavaScript解释器并等待它继续构建DOM之前(因为您的脚本可能会使用document.write添加到HTML令牌流)。您可以在支持它们的浏览器上使用async or defer attributes承诺您不会使用document.write的浏览器,但是......


更新:您已经说过:

  

因为prepareData是长时间函数,我认为浏览器可以在构建DOM树时执行它。不幸的是'$(document).ready'在prepareData完成之前触发。问题是如何教'$(document).ready'等待准备好的数据

ready处理程序在processData运行时可能触发的唯一方法是processData使用异步ajax(或alert周围的几个边缘条件,{ {1}}之类的,但我认为你没有这样做。如果是,则无法将结果作为函数的返回值返回(尽管您可以返回由于ajax回调而继续更新的对象)。否则,这是不可能的:浏览器上的JavaScript是单线程的,confirm处理程序将排队等待解释器完成其先前的任务(ready)。

如果processData没有做任何异步操作,我怀疑你看到的任何症状让你认为processData处理程序在 {{1}期间解雇有不同的原因。

但是在异步的情况下,有三个选项:

  1. 如果您无法控制想要保留的现成处理程序,可以查看jQuery的holdReady功能。致电ready以暂停活动,并使用processData停止举办活动。

  2. 重新安排$.holdReady(true);处理程序非常简单。这是我如何做到的(请注意,我已将所有内容都包含在作用域函数中,因此这些不是全局变量):

    $.holdReady(false);

    请注意,我很高兴在ready函数中使用(function() { var data = processData(); $(onPageReady); function processData() { } function onPageReady() { if (!data.ready) { // Wait for it to be ready setTimeout(onPageReady, 0); // 0 = As soon as possible, you may want a // longer delay depending on what `processData` // is waiting for return; } } })(); ,因为我知道它在那里;在data返回之前,该函数不会运行。但是我假设onPageReady正在返回一个通过ajax调用慢慢填充的对象,所以我在对象上使用了一个processData标志,当所有数据准备就绪时它将被设置。

  3. 如果您可以更改processData,那么有一个更好的解决方案:让ready在完成时触发就绪处理程序。以下是processData完成所需操作的代码:

    processData

    这是有效的,因为如果DOM尚未准备好,那只是安排调用。如果DOM 已经准备就绪,jQuery将立即调用您的函数。这可以防止凌乱的循环。