JSONP делает асинхронный вызов? - PullRequest
7 голосов
/ 19 февраля 2012

Я новичок в jsonp и понимаю, что JSONP - это техника, которая создает динамический <script src="..."> тег, который оборачивает возвращаемый JavaScript (или JSON-объект) функцией обратного вызова.

Но если я не ошибаюсь, атрибут src в теге скрипта будет сдерживать все последующие исполнения до загрузки скрипта, так как это может быть асинхронный вызов?

Ответы [ 7 ]

6 голосов
/ 22 ноября 2012

На самом деле, как вы можете прочитать о здесь и здесь динамически созданные <script src=".."> элементы после завершения загрузки DOM НЕ будут блокироваться, и, таким образом, они будут асинхронными.По крайней мере, в порядке их создания.

в кавычках из http://calendar.perfplanet.com/2010/the-truth-about-non-blocking-javascript/

При динамической вставке скрипта неблокирующая загрузка начинается немедленно.Сценарий выполняется сразу после полной загрузки.В большинстве браузеров порядок выполнения не гарантируется, хотя Firefox <4 и Opera будут выполнять сценарии в том порядке, в котором они были вставлены.Этот общий подход поддерживается во всех основных браузерах. </p>

3 голосов
/ 25 ноября 2012

Я думаю, что ваш вопрос состоит из двух частей.

Во-первых, JSONP, по сути, не относится к динамическим тегам сценариев, скорее динамические теги сценариев - это техника, используемая рука об руку с JSONP.

JSONP - это метод, который позволяет сайту загружать контент из доменов, отличных от ORIGIN, используя толерантность браузера к тегам SCRIPT с src, указывающим на внешние домены. (Вы должны знать это, пройдя по ссылкам, приведенным в других ответах).

С другой стороны, динамические теги SCRIPT обеспечивают асинхронную природу для любого сценария, будь то JSONP или иным образом.

Дело в том, что всякий раз, когда браузер нажимает на тег SCRIPT в документе, он останавливает большинство других операций (особенно рендеринг DOM) до тех пор, пока этот скрипт не будет загружен. Это влияет на восприятие пользователями того, насколько отзывчивым является сайт. Эффект от этого еще хуже, если скрипт не вносит непосредственного вклада в основной контент сайта (такой как Google Ads, Tweets или Facebook Timeline (если вы не Марк Z.: P) и т. Д.)

Чтобы избежать этой проблемы, вы можете вставлять динамические теги SCRIPT на страницу, когда она полностью загружена в браузере (т.е. событие готово / загружено). Затем браузер автоматически загрузит новый сценарий, но у пользователя есть полная (почти) страница, созданная для него, что создает впечатление быстрой загрузки. В этом смысле динамические сценарии могут быть асинхронными при загрузке страницы.

Однако на практике большинство сценариев, используемых таким образом, являются сценариями JSONP, расположенными в разных доменах, хотя это и не является обязательным требованием.

Надеюсь, это имеет смысл.

Для загрузки TRUE асинхронного скрипта вы должны обратиться к атрибуту HTML5 sync :

2 голосов
/ 26 ноября 2012

Вызов асинхронный, да.Возможно, вы путаете поведение тега скрипта, когда страница загружается и когда страница уже загружена.

Поскольку страница загружается браузером, все теги HTML с ресурсами (теги изображений, теги ссылок и т. Д.) Загружаются асинхронно и не прерывают задачу рендеринга браузера.Это имеет улучшение оптимизации производительности рендеринга страницы.

Единственный тег, который не следует этому правилу, является тегом script.Поскольку браузер должен обеспечивать порядок сценариев, он не будет загружать их параллельно.Кроме того, браузер должен учитывать динамические изменения в HTML-документе, сделанные из сценария с использованием document.write, и по этой причине он будет оценивать сценарий сразу после его загрузки.Таким образом, это поведение по умолчанию в браузерах в отношении тегов скрипта с файлом src: они будут блокировать рендеринг страницы, загружаться последовательно и будут оцениваться, как только они будут загружены.Существуют методы, позволяющие избежать этого, например, размещение сценариев внизу документа (сценарии будут загружаться и оцениваться только после визуализации документа) или использование новых атрибутов тега сценария HTML5 «async» и «defer»: http://blogs.microsoft.co.il/blogs/gilf/archive/2011/12/29/the-async-and-defer-script-attributes-in-html5.aspx.

Возвращаясь к JSONP: да, он асинхронный в том смысле, что не блокирует дальнейшее поведение браузера (страница уже обработана).Это асинхронность, которую обеспечивают обычные вызовы AJAX.

1 голос
/ 23 ноября 2012

Включения JSONp на самом деле не работают как вызовы AJAX, так как они немного хакерские.Если бы меня нажимали, чтобы поместить их в любое поле, я бы использовал «асинхронный».

Я думаю, наиболее важной особенностью является то, что «возвращаемое значение» будет отображаться в другом событии.* Вы не можете написать:

var return_value = do_jsonp("my function");

Вы должны написать это вместо: (или использовать какую-то библиотеку обещаний)

do_jsonp("my function", function (return_value) {});

Итак, когда скрипт в ресурсе JSONpфактически исполняется не актуально.Все, что имеет значение, это то, что это происходит в другом событии.

0 голосов
/ 24 ноября 2012

вы как бы неправильно понимаете слово "асинхронный".исключение javascript является асинхронным, что означает, что каждая строка javascript-кода, которая появляется после того, как вы вставили свой скрипт-тег, выполняется.

пример:

var yourCB = function(result) { ... }

// i use the script injection from neiker here (without the async = true, to illustrate that this has nothing to do with the asynchronous nature JSONP 
var ga = document.createElement('script'); 
ga.type = 'text/javascript'; 
ga.src = 'http://domain/api/...?callback=yourCB';
var s = document.getElementsByTagName('script')[0]; 
s.parentNode.insertBefore(ga, s);

// everything after the script insertion is excecuted, even if your jsonp-callback hasnt been called. as soon as your script-request has finished yourCB is called.
alert('THIS IS ALERTED EVEN IF yourCB HASNT BEEN CALLED');
0 голосов
/ 21 ноября 2012
var ga = document.createElement('script'); 
ga.type = 'text/javascript'; 
ga.async = true;
ga.src = 'http://domain/api/...?callback=something';
var s = document.getElementsByTagName('script')[0]; 
s.parentNode.insertBefore(ga, s);

В любом случае, вы не можете использовать jQuery? Если нет, попробуйте это: https://github.com/ded/reqwest

0 голосов
/ 20 ноября 2012

Этот вопрос, связанный с , должен пролить свет на ваш вопрос.

Узлы сценариев, добавленные динамически с использованием javascript, выполняются асинхронно и не блокируют выполнение других сценариев.

...