Что возвращает $ .getScript и что он делает для определения области видимости? - PullRequest
0 голосов
/ 26 апреля 2018

Я создаю плагин, в который хочу загрузить несколько скриптов и для каждого из них запустить функцию plugin.

Я создал набор тестов / примеров (код ниже).

Вопросы:

  1. AJAX передает обычный data, textStatus, jqxhr набор аргументов. Но, видимо, также создает область, в которой доступна функция plugin. Ничего не могу найти об этом в документации. Подробнее / объяснение, пожалуйста!

  2. Какого черта this, который, кажется, находится в области видимости?

  3. Третий пример, где я запускаю скрипт get, отображая список имен скриптов, работает как ожидалось.

  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";
}

two.js

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

Three.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 .

1 Ответ

0 голосов
/ 26 апреля 2018
  1. Функция обратного вызова запускается в глобальном контексте после загрузки скрипта. Поскольку скрипт определяет глобальную переменную plugin, доступ к нему можно получить из функции обратного вызова.

  2. $.getScript не устанавливает конкретный контекст, поэтому this будет глобальным window объектом. this.plugin совпадает с window.plugin, который является глобальной переменной.

  3. Это верно.

  4. $.getScript возвращает обещание, но вы не толкаете их на plugs, вы просто нажимаете plugin.

Назначьте результат от .map() до plugs, чтобы получить правильный массив обещаний.

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