我正在编写一个脚本,可以根据需要使用AJAX调用从服务器获取指定的资源r
(当然,默认情况下是异步),然后调用回调函数{{ 1}}与服务器返回的资源。
为了提高效率,如果已经请求了给定资源,我希望脚本不启动另一个AJAX调用,而是在已经加载资源完成下载时执行回调:
的JavaScript
f
在 var nowLoading = {};
/**
* @param {String} r - The resource identifier
* @param {Object} f - Callback function with returned resource
*/
function Load(r, f)
{
if (nowLoading.hasOwnProperty(r))
{
// the given resource is already being requested, listen to it being finished
nowLoading[r].OnReady = function () {
// ...
f(resource);
};
}
else
{
// make a new request
var xhr = XHRFactory.Spawn();
nowLoading[r] = xhr;
xhr.OnReady = function () {
// ...
f(resource);
};
xhr.open('GET', url);
xhr.send();
}
};
和 nowLoading.hasOwnProperty(r)
之间,是否存在边缘可能性语句吗
或者我在这方面误解了JS,nowLoading[r].OnReady = fn
只能在顺序语句执行完毕后才会发生?
前者意味着附加到OnReady
属性的回调可能永远不会被执行,因为nowLoading
在附加任何内容之前就已经发生了。
注意:OnReady
是OnReady
的特殊自定义案例。另请注意,为简单起见,XHR.onreadystatechange
不会清除先前的处理程序,而是添加一个新的处理程序。
答案 0 :(得分:1)
Javascript使用单个线程执行(有一些引擎可以尝试多线程,但是它们会让事情看起来像是在一个线程上发生的。)
现在,针对您的问题。因为你正在运行一些代码,并且没有双线程(当调用完成时,它将注册回调以在主线程上运行。)
所以,不,代码不可能在语句之间运行,因为它运行在同一个线程上,并且只有在当前执行堆栈完全展开后才会运行。
以下是Javascript事件循环的Google最佳结果,该结果应概述后台发生的事情,以便将所有这些工作结合在一起。
http://2014.jsconf.eu/speakers/philip-roberts-what-the-heck-is-the-event-loop-anyway.html
至于问题的第二部分:
前者意味着可以附加回调 由于OnReady发生,nowLoading的属性永远不会被执行 在附上任何东西之前。
Javascript的模型确实意味着如果调用同步完成,可能会发生这种情况。但是,在这种情况下,由于您使用的是Ajax,因此永远不会同步执行调用,因此将始终注册回调。
答案 1 :(得分:1)
不,这是不可能的。这是JS的一个特色:
在完成任何其他消息之前,将完全处理每条消息 处理。这在推理你的时候提供了一些不错的属性 程序,包括每当一个函数运行的事实,它不能 被抢占,将在任何其他代码运行之前完全运行(和 可以修改函数操作的数据)。这与C不同 例如,如果函数在一个线程中运行,则可以在其中停止 任何在另一个线程中运行其他代码的点。
因此,一旦开始运行某些同步代码,异步代码将等待同步代码完成。
答案 2 :(得分:1)
异步函数就是:Asyncronous。但是,由于JS是单线程的(除非你使用的是HTML5's Web Workers,这是真正的多线程,但在这里并非如此),这意味着事件回调函数在运行时引擎之前不会执行免费。
所以,答案是否定的。代码中的回调不能在两个同步语句之间执行。