JSONP是否进行异步调用?

问题描述 投票:7回答:7

我是jsonp的新手,我知道JSONP是一种创建动态<script src="...">标记的技术,它使用回调函数包装返回的JavaScript(或JSON对象)。

但是如果我没有弄错的话,脚本标签中的src属性将阻止所有进一步的执行,直到脚本加载,那么如何才能进行异步调用?

javascript asynchronous jsonp
7个回答
0
投票

This相关问题应该对你的问题有所了解。

使用javascript动态添加的脚本节点是异步执行的,它们不会阻止其他脚本的执行。


6
投票

实际上,正如你可以阅读herehere在DOM完成加载后动态创建的<script src="..">元素将不会阻塞,并且它们将是asynchrounus ..至少按照它们的创建顺序。

http://calendar.perfplanet.com/2010/the-truth-about-non-blocking-javascript/ qutoted

动态插入脚本时,立即开始非阻塞下载。该脚本在完全下载后立即执行。在大多数浏览器中,虽然Firefox <4和Opera将按照插入顺序执行脚本,但不保证执行顺序。所有主流浏览器都支持这种通用方法。


3
投票

我认为你的问题有两个部分。

首先,JSONP本质上不是关于动态脚本标记,而是动态脚本标记是与JSONP一起使用的技术。

JSONP是一种允许站点加载来自ORIGIN以外的不同域的内容的方法,利用浏览器对SCRIPT标记的容忍度,src指向外部域。 (你应该通过浏览其他答案中给出的链接来了解这一点)。

另一方面,动态SCRIPT标记为JSONP或其他任何脚本提供异步性质。

重点是,只要浏览器访问文档上的SCRIPT标记,它就会停止大多数其他活动(特别呈现DOM),直到下载该脚本为止。这会影响用户对网站响应速度的体验。如果脚本没有直接影响网站的主要内容(例如Google广告,推文或Facebook时间线(假设您不是Mark Z.:P)等),这种情况的影响会更严重

为了避免这个问题,一旦它完全加载到浏览器上(即就绪/加载事件),就可以将动态SCRIPT标记注入页面。然后浏览器将静默加载新脚本,但用户已经(几乎)为他呈现了整页(给出了快速加载的印象)。从这个意义上讲,动态脚本可以与页面加载异步。

但是,实际上,以这种方式使用的大多数脚本都是驻留在不同域上的JSONP脚本,尽管这不是必需的。

希望这是有道理的。

对于TRUE异步脚本加载,您应该查看HTML5 sync属性:


2
投票

该调用是异步的,是的。也许在页面加载和页面加载时,您会混淆脚本标记的行为。

当浏览器加载页面时,所有带有资源的HTML标签(图像标签,链接标签等)都会异步下载资源,不会中断浏览器渲染任务。这有改进优化页面呈现的性能。

唯一不遵循此规则的标记是脚本标记。因为浏览器必须确保脚本的顺序,所以它不会并行加载它们。此外,浏览器必须使用document.write对脚本生成的HTML文档进行动态更改,因此它将在下载后立即对脚本进行评估。因此,这是浏览器关于带有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
投票

JSONp包括不像AJAX调用那样真正起作用,因为它们有点像黑客。如果我被迫把它们放在任何一个盒子里,我会选择“异步”。

我想最重要的特质是“回归价值”会出现在另一个事件中。

你不能写:

var return_value = do_jsonp("my function");

你必须写这个:(或使用某种承诺库)

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

因此,当JSONp资源中的脚本实际执行时不相关。所有相关的是它发生在不同的事件中。


0
投票

你有点误解“异步”这个词。 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');

-2
投票
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

© www.soinside.com 2019 - 2024. All rights reserved.