Javascript Ajax会导致死锁吗?

时间:2013-05-09 08:53:14

标签: javascript ajax multithreading deadlock

我有一个思想实验。在我的代码中,我有一个全局变量说var changeMe;,我正在做几个Ajax调用。

 //call One -- third param is the callback function
    ajaxFunction(url1, params,function(data){
        changeMe = data;
    });

//call Two
    ajaxFunction(url2, params,function(data){
        changeMe = data;
    });

所以changeMe值取决于哪个Ajax调用最后完成,这意味着最后完成的调用将覆盖该值。

如果这两个来电完全在同一时间,同一时间戳完成怎么办?

由于Javascript是单线程的,我们通常不会遇到此问题,但在setTimeout和Ajax调用的情况下可能会出现这种情况。我不知道如何精确地复制这个问题,所以它仍然是一个思想实验。

那么在多线程条件下如何处理死锁呢?

我更喜欢changeMe的答案url1url2以及明确的情况说明。

提前致谢

2 个答案:

答案 0 :(得分:13)

Javascript有一个事件队列。这意味着它会逐个处理所有事件(用户触发的事件,setTimeout事件,ajax返回事件),因为它们来了

你不能对执行顺序做出假设,这绝对不是正确的方法。这并不意味着你不能做同步。例如:

function processURLs() {
    var url1 = "http://www.url1.com/";
    var url2 = "http://www.url2.com/";
    var data1 = null;
    var data2 = null;

    ajaxFunction(url1, params, function(data){
        data1 = data;
        if( data2 !== null ) {
            process(data1, data2);
        }
    });

    ajaxFunction(url2, params, function(data){
        data2 = data;
        if( data1 !== null ) {
            process(data1, data2);
        } 
    });
}

你说javascript是单线程的。那就对了。当有要处理的事件时,该线程会保持循环并从此队列中弹出事件。

即使调用完全在同一时间和相同的时间戳完成,也会有一个将在另一个之前排队到此事件队列(因为您的系统会以某种顺序将消息传送到javascript进程)。 / p>

如果您想了解 javascript计时器的工作方式,我会深深推荐阅读John Resig's blog post about it

如果您想了解有关如何将网络事件传递到浏览器(javascript)的更多信息,您应该了解OSI Model

例如,您的浏览器位于OSI第7层(应用程序)中,但网络事件的顺序将在下面决定(第3层到第6层)。

总结答案:没有人可以告诉你changeMe将是url1或url2。 Javascript不会在这里决定订单,它将在更深层次决定(您的网卡,您的操作系统等)。

答案 1 :(得分:5)

在Javascript中,异步操作在后台运行,但所有Javascript代码(包括回调)都在前台线程中运行。因此,设计实际上不可能同时执行两个回调。

如果两个异步操作在完全相同的时间完成,它们将同时发出完成信号,然后Javascript调度程序将选择两个回调中的一个首先运行。

首先回调的是实现和操作系统特定的,出于所有意图和目的,您可以假设它是随机的。