【问题标题】:What does $.getScript return, and what does it do to scope?$.getScript 返回什么,它对作用域有什么作用?
【发布时间】:2018-10-07 13:26:56
【问题描述】:

我正在创建一个插件,我想在其中加载一些脚本,并为每个脚本运行 plugin 函数。

我创建了一个set of tests/examples(代码如下)。

问题:

  1. AJAX 传入通常的data, textStatus, jqxhr 参数集。但显然也创建了一个可以使用plugin 函数的范围。在文档中找不到任何关于此的内容。请提供更多详细信息/解释!

  2. 这到底是什么this 似乎在范围内?

  3. 我通过映射脚本名称列表运行 get script 的第三个示例按预期工作。

  4. 构建延迟列表,然后使用when 运行会出现奇怪的行为。我没有得到功能已经运行的迹象(没有输出),当我消除延迟时,它似乎总是先完成(“完成”打印在其他所有内容之前)。功能是否正在运行?我尝试添加一个alert,但当我使用when时它没有出现。

index.js

var script_names = ["one.js", "two.js", "three.js"];

function as_callback(script_name)
{
  console.log("plugin function run as callback");
  console.log(`$.getScript(${script_name}, (data, textStatus, jqxhr) => plugin());`);
  $.getScript(script_name, (data, textStatus, jqxhr) => plugin());
  console.log();
}

function from_this(script_name)
{
  console.log("plugin function referred to from 'this'");
  console.log(`$.getScript(${script_name}, (data, textStatus, jqxhr) => this.plugin());`);
  $.getScript(script_name, (data, textStatus, jqxhr) => this.plugin());
  console.log();
}

function with_map(script_names)
{
  console.log("with map");
  console.log("string_names: " + JSON.stringify(script_names));
  console.log(`
  script_names.map((x) => 
  {
    $.getScript(x, (data, textStatus, jqxhr) => plugin())
  });
  `);
  script_names.map((x) => 
  {
    $.getScript(x, (data, textStatus, jqxhr) => plugin())
  });
  console.log();
}

function with_push_and_when(script_names)
{
  console.log("build array of deferred and run with when");
  console.log(`
  var plugs = [];
  script_names.map(x => $.getScript(x, (data, textStatus, jqxhr) => plugs.push(plugin)));
  $.when(plugs).done(console.log("done"));
  `);
  var plugs = [];
  script_names.map(x => $.getScript(x, (data, textStatus, jqxhr) => plugs.push(plugin)));
  $.when(plugs).done(console.log("done"));
  console.log();
}

as_callback('one.js');

setTimeout("from_this('two.js')", 2000);

setTimeout("with_map(script_names)", 4000);

setTimeout("with_push_and_when(script_names)", 6000);

var plugs = [];
script_names.map(x => $.getScript(x, (data, textStatus, jqxhr) => plugs.push(plugin)));
setTimeout("console.log('run when in global scope');$.when(plugs).done(console.log('done'))", 8000);

one.js

var plugin = function()
{
  console.log("one.js\n\n");
  // alert("one");
  return "one";
}

两个.js

var plugin = function()
{
  console.log("two.js\n\n");
  return "two";
}

三个.js

var plugin = function()
{
  console.log("three.js\n\n");
  return "three";
}

输出

plugin function run as callback
$.getScript(one.js, (data, textStatus, jqxhr) => plugin());

one.js


plugin function referred to from 'this'
$.getScript(two.js, (data, textStatus, jqxhr) => this.plugin());

two.js


with map
string_names: ["one.js","two.js","three.js"]

  script_names.map((x) => 
  {
    $.getScript(x, (data, textStatus, jqxhr) => plugin())
  });


two.js


three.js


one.js


build array of deferred and run with when

  var plugs = [];
  script_names.map(x => $.getScript(x, (data, textStatus, jqxhr) => plugs.push(plugin)));
  $.when(plugs).done(console.log("done"));

done

run when in global scope
done

注意: 我将接受的答案添加到 repl.it

【问题讨论】:

  • 在此处发布您的代码,而不仅仅是在远程站点。您可以使用Stack Snippets 使其可执行。
  • 您阅读文档了吗?
  • @Barmar -- 只有当你有一个 JS 文件时才有效。我不知道如何演示在那个环境中加载外部脚本。
  • "脚本是在全局上下文中执行的,所以它可以引用其他变量并使用jQuery函数。包含的脚本会对当前页面产生一些影响。"
  • @epascarello 是的。我是 RTFM。我一定错过了它说明回调上下文中可用的环境或范围的部分。

标签: javascript jquery ajax deferred .when


【解决方案1】:
  1. 加载脚本后,回调函数在全局上下文中运行。由于脚本定义了全局变量plugin,所以可以从回调函数中访问。

  2. $.getScript 没有设置特定的上下文,因此this 将是全局window 对象。 this.pluginwindow.plugin 一样,都是全局变量。

  3. 没错。

  4. $.getScript 返回一个承诺,但你没有将它们推送到plugs,你只是在推送plugin

.map() 的结果分配给plugs 以获得正确的promise 数组。

var plugs = script_names.map(x => $.getScript(x, (data, textStatus, jqxhr) => plugin()));
$.when(plugs).done(console.log("done"));

【讨论】:

  • 谢谢@Barmar。这是有道理的,答案#4是如此明显,我应该自己弄清楚。
猜你喜欢
  • 1970-01-01
  • 2011-01-14
  • 1970-01-01
  • 1970-01-01
  • 2019-04-26
  • 2016-04-29
  • 2017-03-02
  • 2012-10-04
  • 1970-01-01
相关资源
最近更新 更多