jquery - 我可以在没有回调的情况下使用 jquery getScript() 吗?

标签 jquery getscript

我需要在另一个 js 文件中使用来自外部 js 文件的 javascript 函数。这基本上是我试过的代码:

$.getScript('js/myHelperFile.js');
myHelperFunction();

这不起作用 - 我收到“myHelperFunction 未定义”的错误消息。

但是,此代码有效:
$.getScript('js/myHelperFile.js', function(){myHelperFunction();});

我特别希望能够以第一种方式执行此操作 - 在我的文件顶部加载文件,然后从那里开始使用我需要的任何功能。这是可能的,还是我误解了 getScript 的工作原理?

最佳答案

使用 jQuery.getScript 目前*不可能做到“第一种方式”因为它只支持异步操作,所以调用后立即返回。

因为当脚本尝试调用 myHelperFunction() 时,它会在您的脚本下载之前返回。 , myHelperFunctionundefined并导致该错误。

*请参阅此答案底部的更新,了解一种有前途的新方法,该方法最终将允许您编写几乎符合您所需风格的代码。

您可以使用 jQuery.ajax 来做到这一点与 async设置设置为 false代码是这样的:

$.ajax({
  url: 'js/myHelperFile.js',
  async: false,
  dataType: "script",
});

myHelperFunction();

但是documentation指出:

synchronous requests may temporarily lock the browser, disabling any actions while the request is active.



这是一件非常糟糕的事情。如果提供 myHelperFile.js 的服务器在任何时候响应都很慢( 在某个时刻发生)页面将变得无响应,直到请求完成或超时。

接受在整个 jQuery 中大量使用的回调样式会是一个更好的主意。
$.getScript('js/myHelperFile.js', function () {
   myHelperFunction();
});

您也不需要使用匿名函数,您可以将代码放在命名函数中:
function doStuffWithHelper() {
   myHelperFunction();
}

$.getScript('js/myHelperFile.js', doStuffWithHelper);

如果在调用 myHelperFunction 之前需要加载多个依赖项除非您设置某种系统来确定是否在执行代码之前下载了所有依赖项,否则这将不起作用。然后,您可以在所有 .getScript 上设置回调处理程序。在运行代码之前调用以检查所有依赖项是否已加载。
var loadedScripts = {
    myHelperFile: false,
    anotherHelperFile: false
};

function doStuffWithHelper() {
    // check to see if all our scripts are loaded
    var prop;
    for (prop in loadedScripts) {
        if (loadedScripts.hasOwnProperty(prop)) {
            if (loadedScripts[prop] === false) {
                return; // not everything is loaded wait more
            }
        }
    }

    myHelperFunction();
}

$.getScript('js/myHelperFile.js', function () {
    loadedScripts.myHelperFile = true;
    doStuffWithHelper();
});
$.getScript('js/anotherHelperFile.js', function () {
    loadedScripts.anotherHelperFile = true;
    doStuffWithHelper();
});

如您所见,这种方法变得复杂且无法快速维护。

如果确实需要加载多个依赖项,最好使用诸如 yepnope.js 之类的脚本加载器。去做吧。
yepnope( {
        load : [ 'js/myHelperFile.js', 'js/anotherHelperFile.js' ],
        complete: function () {
            var foo;
            foo = myHelperFunction();
            foo = anotherHelperFunction(foo);
            // do something with foo
        }
} );

Yepnope 使用回调就像 .getScript所以你不能使用你想要坚持的顺序样式。这是一个很好的权衡,因为做多个同步 jQuery.ajax连续调用只会加剧该方法的问题。

更新 2013-12-08

jQuery 1.5 release , 提供了另一种纯 jQuery 方式。从 1.5 开始,所有 AJAX 请求都返回 Deferred Object所以你可以这样做:
$.getScript('js/myHelperFile.js').done(function () {
   myHelperFunction();
});

作为异步请求,它当然需要回调。然而,使用 Deferreds 比使用 $.when() 的传统回调系统有巨大的优势。您可以轻松地将其扩展为加载多个先决条件脚本,而无需您自己复杂的跟踪系统:
$.when($.getScript('js/myHelperFile.js'), $.getScript('js/anotherHelperFile.js')).done(function () {
  var foo;
  foo = myHelperFunction();
  foo = anotherHelperFunction(foo);
  // do something with foo
});

这将同时下载两个脚本,并且仅在下载两个脚本后才执行回调,就像上面的 Yepnope 示例一样。

更新 2014-03-30

我最近阅读 an article这让我意识到一个新的 JavaScript 特性,它可能在 future 启用你想要使用的那种看起来像程序但异步的代码! Async Functions将使用 await暂停执行 async 的关键字直到异步操作完成。坏消息是它目前计划包含在 ES7 中,还有两个 ECMAScript 版本。
await依赖于您正在等待的异步函数返回 Promise .我不确定浏览器实现的行为,如果它们需要一个真正的 ES6 Promise 对象,或者其他 Promise 实现(如 jQuery 从 AJAX 调用返回的一个)是否就足够了。如果需要 ES6 Promise,则需要包装 jQuery.getScript带有返回 Promise 的函数:
"use strict";
var getScript = function (url) {
  return new Promise(function(resolve, reject) {
    jQuery.getScript(url).done(function (script) {
      resolve(script);
    });
  });
};

然后你就可以用它来下载和await在继续之前:
(async function () {
  await getScript('js/myHelperFile.js');
  myHelperFunction();
}());

如果您今天真的决心以这种风格写作,您可以使用 asycawait然后使用 Traceur将您的代码转换为可在当前浏览器中运行的代码。这样做的额外好处是您还可以使用许多 other useful new ES6 features也是。

关于jquery - 我可以在没有回调的情况下使用 jquery getScript() 吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8026191/

相关文章:

javascript - getScript 创建 ReferenceError

jquery - 如何在ZK中使用jQuery点击

javascript - 如何用javascript在视频结束前隐藏文本

javascript - 我应该使用 jQuery 的 getScript() 还是大量的 <script> 标签?

javascript - 使用 getScript 异步加载脚本

javascript - 从 Angular 2 项目调用 JavaScript 文件

javascript - 从 javascript 设置字段

php - 无法根据来自 php 的 json id 在 JavaScript 中设置变量

javascript - 生产中来自 Customizer 的 Wordpress 内联样式

javascript - Play Framework - 在函数中定义我的 Javascript 文件