在Google';s API javascript示例

在Google';s API javascript示例,javascript,google-api,Javascript,Google Api,在Google为其API提供的各种javascript示例(例如)中,他们使用以下代码从html加载脚本: <script async defer src="https://apis.google.com/js/api.js" onload="this.onload=function(){};handleClientLoad()" onreadystatechange="if (this.readyState === 'complete') this.onload()"

在Google为其API提供的各种javascript示例(例如)中,他们使用以下代码从html加载脚本:

<script async defer src="https://apis.google.com/js/api.js" 
    onload="this.onload=function(){};handleClientLoad()" 
    onreadystatechange="if (this.readyState === 'complete') this.onload()">
</script>

我的理解是,
async/defer
告诉浏览器什么时候加载和执行脚本,这两者之间有些矛盾。我有几个问题:

  • 在本例中同时使用
    async
    defer
    有什么意义 背景
  • 谷歌为什么选择使用这种技术?有没有 业绩还是其他好处
  • onload
    事件中,为什么他们首先将空函数(
    function(){};
    )分配给事件 在调用handleClientLoad()之前
  • 如果我想将整个javascript移动到一个单独的js文件中, 加载这两个脚本的最佳方法是什么?自从新的js文件 将依赖于api.js并且不能异步加载

  • 谢谢。

    这一点在中得到了很好的介绍,其中包括以下方便的图形:

    一,。在此上下文中同时使用async和defer的意义是什么

    如果浏览器支持
    async
    ,它将忽略
    defer
    ,并执行异步工作。如果不支持,但支持延迟,则改为延迟。如果不支持这两种方法,脚本将阻止DOM解析,但所有现代浏览器都至少支持一种

    2.谷歌为什么选择使用这种技术?它是否有任何性能或其他好处

    async
    在不阻止DOM解析和呈现的情况下获取脚本,并在可用时立即运行脚本,即使DOM解析和呈现仍在进行中
    defer
    还将避免阻止DOM解析和呈现,但在解析完成之前(例如,可能稍后)不会运行脚本

    三,。在onload事件中,为什么在调用
    handleClientLoad()
    之前,他们首先为事件分配一个空函数(
    function(){};

    如果您查看
    onreadystatechanged
    ,这一点就很清楚了:它基本上确保了
    handleClientLoad
    只由GAPI调用一次,而不是潜在的两次(一次由
    onload
    调用,一次由
    onreadystatechanged
    调用)

    四,。如果我想将整个javascript移动到一个单独的js文件中,那么加载这两个脚本的最佳方法是什么?因为新的js文件将依赖于api.js,不能异步加载

    嗯,它可以异步加载,您只需使用
    api.js
    处理竞争条件即可。我可能会:

  • 脚本
    标记加载api.js上方的内联脚本中设置
    handleClientLoad
    ,如下所示:

    var clientLoaded = false;
    function handleClientLoad() {
        if (!clientLoaded &&
            typeof mainScriptLoad !== "undefined" &&
            typeof gapi !== "undefined") {
            clientLoaded = true;
            mainScriptLoad();
        }
    }
    
  • mainScriptLoad
    放在单独的文件中

  • 在单独文件的末尾,调用
    handleClientLoad

  • 这样:

    • 如果您的脚本首先运行,它将调用
      handleClientLoad
      ,但是
      handleClientLoad
      将看到GAPI尚未加载,并且不会执行任何操作;稍后,当GAPI加载时,它将调用
      handleClientLoad
      ,这将调用
      mainScriptLoad
      ,因为一切都准备好了
    • 如果脚本在GAPI加载后运行,它将调用
      handleClientLoad
      ,但是
      handleClientLoad
      将看到主脚本尚未加载,并且不会尝试调用它。稍后,当脚本加载并调用
      handleClientLoad
      时,
      handleClientLoad
      将调用
      mainScriptLoad
      ,因为一切就绪

    最后一个问题-为什么需要
    onload
    onreadystatechange
    ?为了支持不同的浏览器?@danielv:是的
    script
    标记没有用于引发时间迷雾中的
    load
    事件,而是引发了
    onreadystatechanged
    事件。@danielv:谢谢!固定的。