代码之家  ›  专栏  ›  技术社区  ›  Artem Barger

JavaScript同步选项

  •  10
  • Artem Barger  · 技术社区  · 17 年前

    我想知道什么时候有在JavaScript代码中执行同步的解决方案。例如,我有以下情况:我试图缓存AJAX调用的一些响应值,问题是,有可能同时执行多个调用,因此会导致代码中的竞争条件。所以我很想找到解决办法?有人有这个想法吗?

    6 回复  |  直到 17 年前
        1
  •  8
  •   Chad Grant    17 年前

    jQuery的基本代码:(没有测试和缩写……但我做过类似的事情)

    var needAllThese = {};
    
    $(function(){
    
          $.ajax("POST","/somepage.aspx",function(data) {
              needAllThese.A = "VALUE";
          });
    
          $.ajax("POST","/somepage2.aspx",function(data) {
              needAllThese.B = "VALUE";
          });
    
          $.ajax("POST","/somepage3.aspx",function(data) {
              needAllThese.C = "VALUE";
          });
    
          startWatching();
    });
    
    function startWatching() {
       if (!haveEverythingNeeded()) {
           setTimeout(startWatching,100);
           return;
       }
       everythingIsLoaded();
    }
    
    function haveEverythingNeeded() {
        return needAllThese.A && needAllThese.B && needAllThese.C;
    }
    
    function everythingIsLoaded() {
       alert("Everything is loaded!");
    }
    

    编辑:(回复:您的评论)

       var cache = {};
    
       function getSomeValue(key, callback) {
           if (cache[key]) callback( cache[key] );
    
           $.post( "url",  function(data) {
               setSomeValue(key,data);
               callback( cache[key] );
           }); 
       }
    
       function setSomeValue(key,val) {
            cache[key] = val;
       }
    
       $(function(){       
            // not sure you would need this, given the code above
            for ( var i = 0; i < some_length; ++i)  {
                $.post( "url", function(data){ 
                    setSomeValue("somekey",data); 
                });
            }
    
            getSomeValue("somekey",function(val){            
                 $("#element").txt( val );              
            };            
        });
    
        2
  •  6
  •   fforw    17 年前

        3
  •  4
  •   Artem Barger    17 年前

    我已经找到了解决我问题的办法。我不得不说,它并不像我想要的那么完美,但到目前为止,它奏效了,我认为这只是暂时的变通。

    $.post( "url1", function( data)
    {
         // do some computation on data and then
         setSomeValue( data);
    });
    
    var setSomeValue = ( function()
    {
        var cache = {};
        return function( data)
        {
            if ( cache[data] == "updating")
            {
                 setTimeout( function(){ setSomeValue( data);}, 100);
                 return;
            }
            if ( !cache[date])
            {
                 cache[date] = updating;
                 $.post( "url2", function( another_data)
                 {
                      //make heavy computation on another_data
                      cache[data] = value;
                      // update the UI with value
                 });
            }
            else
            {
                 //update the UI using cached value
            }
        }
    })();
    
        4
  •  3
  •   Bjorn    17 年前

    是的,您可以使xmlHttpRequests同步,在非IE设置中 asynch option 在IE浏览器中的open方法上为false do the same 使用bAsync参数。

        5
  •  3
  •   Yuval Adam    17 年前

    顺便说一句,浏览器现在引入了工作线程,这将允许JS中的并发性,但目前情况并非如此。

    JS通过回调为您提供了一个非常好的解决方案。对于您要发送的每个异步事件,请为其附加一个适当的回调函数,该函数将正确处理该事件。 同步

        6
  •  1
  •   Colin Saxton    8 年前

    我知道这已经太晚了,但我想我会做出改进。Artem Barger提出了自己的解决方案,如果缓存值为“更新”,则使用setTimeout。..相反,只需将函数标记到缓存值对应的链接队列上,这样你就有了一个对象,它保存了实际的缓存数据,并且一旦数据返回,函数队列就可以调用缓存数据。

    如果你想了解技术,你可以在队列中设置一个特定的QOS超时,在迭代开始时设置一个秒表,如果达到特定时间,则调用setTimeout返回队列以继续迭代。..我希望你明白了:)-它基本上节省了X次setTimout调用,只需要一次。

    查看上面的Artem Bargers代码,您应该能理解我的建议要点。