【问题标题】:Can Javascript Ajax lead to deadlocks?Javascript Ajax 会导致死锁吗?
【发布时间】:2013-05-09 08:53:14
【问题描述】:

我有一个思想实验。在我的代码中,我有一个全局变量 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 ,以及清晰的情况说明..

提前致谢

【问题讨论】:

  • 在 JavaScript 中,你只有一个线程,所以不会有问题。
  • @Ishank ...谢谢你的朋友......但我没有得到一个简单的答案......
  • 在 javscript 中维护了一个事件队列,下一个 ajax 将在上一个完成时启动..
  • 他们不会。即使两者(以某种方式)在同一时刻完成交付,它们也会被依次处理。 Javascript从不是多线程的(好吧,除了最近引入的显式线程,但那些不能做网络任务)。

标签: javascript ajax multithreading deadlock


【解决方案1】:

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 进程)。

如果你想知道 javascript 计时器是如何工作的,我强烈推荐阅读John Resig's blog post about it

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

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

所以总结一下答案:没有人能告诉你 changeMe 是 url1 还是 url2。 Javascript 不会在这里决定顺序,它会在更深层决定(您的网卡、您的操作系统等)。

【讨论】:

  • 这个答案似乎很合理,但是,在你的答案中包含一些可验证和有信誉的参考资料来支持你的说法会很好。
  • @SamuelLiew:如果您没有在每个答案上复制并粘贴它们,您的评论会非常好。
  • 除此之外,stackoverflow.com/questions/7575589/… 回答了这个问题。
  • @Samuel:我已经为 OSI 模型的描述添加了一个(wiki)链接。它描述了每次通信都会经历的不同抽象层。然后,您可以了解在哪一层中决定了什么。
  • 添加了一个指向 Resig 的关于 javascript 计时器的博客文章的链接。您需要其他参考资料吗?
【解决方案2】:

在 Javascript 中,异步操作在后台运行,但所有 Javascript 代码,包括回调,都在前台线程中运行。所以从设计上来说,两个回调同时执行是不可能的。

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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-12
    相关资源
    最近更新 更多