Javascript Ajax会导致死锁吗?

时间:2021-11-21 00:33:58

I have a thought experiment. In my code I have a global variable say var changeMe; and I'm making few Ajax calls.

我有一个思想实验。在我的代码中,我有一个全局变量say 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;
    });

So changeMe value will depend on which Ajax call finishes last, which means the call that finishes last will overwrite the value.

因此,changeMe值将取决于最后完成的Ajax调用,这意味着最后完成的调用将覆盖该值。

What if both calls finish exactly at the same time, same timestamp?

如果两个呼叫完全同时完成,时间戳相同怎么办?

Since Javascript is single-threaded we normally won't get this problem, but this may arise in the case of setTimeout and Ajax calls. I don't know how I can replicate this issue with precision, so it still remains a thought experiment.

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

So how in multi-threaded conditions is a deadlock handled?

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

I prefer an answer like changeMe will be url1 or url2 , and a clear situation explanation..

我更喜欢像changeMe这样的答案将url1或url2,以及明确的情况说明..

Thanks in advance

提前致谢

2 个解决方案

#1


13  

Javascript has an event queue. It means that it handles ALL events (user-triggered events, setTimeout events, ajax returns events) one by one, as they come.

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

You cannot make assumptions on the execution order, this is definitely not the right way to go. That doesn't mean that you can't do synchronization. For instance:

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

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

You said that javascript is single-thread. That's right. That thread keeps looping and pops the events from this queue when there's events to process.

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

Even if the calls finished exactly at the same time and same timestamp, there will be one that will be enqueued to this event queue before the other (because your system will transmit the messages to the javascript process in some order).

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

If you want to know how javascript timer works with that event queue, i deeply recommend the reading of John Resig's blog post about it

如果你想知道javascript计时器如何与该事件队列一起工作,我深深推荐阅读John Resig关于它的博客文章

If you want more information about how network events are passed to your browser (javascript), you should learn about the OSI Model.

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

For instance, your browser is in the OSI layer 7 (Application), but the order of network events will be decided below (layers 3 to 6).

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

So to sum up the answer: nobody can tell you changeMe will be url1 or url2. Javascript won't decide the order here, it will be decided in deeper layers (your network card, your operating system, etc).

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

#2


5  

In Javascript asynchronous operations run in the background, but all Javascript code, including callbacks, run in the foreground thread. So it is really impossible by design that two callbacks will execute at the same time.

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

If the two asynchronous operations finish at the exact same time both will signal their completion at the same time, and then the Javascript scheduler will pick one of the two callbacks to run first.

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

Which callback goes first is implementation and operating system specific, for all intents and purposes you can assume it will be random.

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

#1


13  

Javascript has an event queue. It means that it handles ALL events (user-triggered events, setTimeout events, ajax returns events) one by one, as they come.

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

You cannot make assumptions on the execution order, this is definitely not the right way to go. That doesn't mean that you can't do synchronization. For instance:

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

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

You said that javascript is single-thread. That's right. That thread keeps looping and pops the events from this queue when there's events to process.

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

Even if the calls finished exactly at the same time and same timestamp, there will be one that will be enqueued to this event queue before the other (because your system will transmit the messages to the javascript process in some order).

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

If you want to know how javascript timer works with that event queue, i deeply recommend the reading of John Resig's blog post about it

如果你想知道javascript计时器如何与该事件队列一起工作,我深深推荐阅读John Resig关于它的博客文章

If you want more information about how network events are passed to your browser (javascript), you should learn about the OSI Model.

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

For instance, your browser is in the OSI layer 7 (Application), but the order of network events will be decided below (layers 3 to 6).

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

So to sum up the answer: nobody can tell you changeMe will be url1 or url2. Javascript won't decide the order here, it will be decided in deeper layers (your network card, your operating system, etc).

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

#2


5  

In Javascript asynchronous operations run in the background, but all Javascript code, including callbacks, run in the foreground thread. So it is really impossible by design that two callbacks will execute at the same time.

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

If the two asynchronous operations finish at the exact same time both will signal their completion at the same time, and then the Javascript scheduler will pick one of the two callbacks to run first.

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

Which callback goes first is implementation and operating system specific, for all intents and purposes you can assume it will be random.

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

相关文章