异步javascript准备函数

asynchronous javascript prepare function

本文关键字:函数 javascript 异步      更新时间:2023-09-26

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

可能是这样的:

var data = function prepareData(){
  ...
}();
$(document).ready(function() {
   // use data to build page
}

如何准备数据供以后使用?由于

为了清晰起见,您需要应该在函数表达式周围使用括号(并且因为在定义和调用函数但不使用返回值的类似情况下,如果没有它们,将会出现语法错误)。此外,当您使用函数表达式时,您不希望给它一个名称。所以:

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

或者使用函数声明代替

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

(为什么不在函数表达式中使用名称?由于各种实现中的错误,特别是IE9之前的Internet Explorer,它将创建两个完全不相关的函数。

然而,我不清楚你想达到什么目的。当浏览器到达script元素时,它交给JavaScript解释器并等待它完成,然后再继续构建DOM(因为脚本可能使用document.write向HTML令牌流添加内容)。您可以使用asyncdefer属性向浏览器承诺您不会在支持它们的浏览器上使用document.write,但是…


更新:下面你说:

因为prepareData是长时间函数,我假设浏览器可以在构建DOM树时执行此函数。不幸的是美元(文档)。ready'在prepareData完成之前触发。问题是如何教'$(文档)。Ready '等待就绪的数据

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

如果processData没有做任何异步的事情,我怀疑无论你看到的症状是什么,让你认为ready处理程序在 processData期间触发有不同的原因。

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

  1. 如果你不能控制你想要的现成处理程序,你可以看看jQuery的holdReady特性。呼叫$.holdReady(true);保持事件,使用$.holdReady(false);停止事件。

  2. 重新调度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;
            }
        }
    })();
    

    请注意,我很高兴在onPageReady函数中使用data,因为我知道它在那里;在processData返回之前,该函数不会运行。但是我假设processData正在返回一个通过ajax调用慢慢填充的对象,所以我在对象上使用了ready标志,当所有数据准备好时将设置。

  3. 如果你可以改变processData,有一个更好的解决方案:让processData触发准备处理程序时,它完成了。以下是processData完成所需操作时的代码:

    $(onPageReady);
    

    这是有效的,因为如果DOM还没有准备好,它只是调度调用。如果DOM已经准备好了,jQuery会立即调用你的函数。