等到ajax请求完成

时间:2013-01-27 12:34:06

标签: javascript ajax

这是一个javascript函数:

  function getValue(key) {
    var value;
    switch(_options.myType){
      case "cookie":
        value = readFromCookie(key);
        break;
      case "localStorage":
        value = readFromLocalStorage(key);
        break;
      case "db":
        //return value from the server
        // how do I wait for the result?
        $.ajax({
            type: "GET",
            url: "123",
            data: { .... },
            success: function(data){
               value = data; 
            }
        });
        break;
    }
    return value;
  };

如果发送ajax请求,我需要等待直到ajax请求完成。我该怎么办?

并非我不能在没有计算值的情况下离开该函数。这意味着我不能在success:处理程序中放置一个函数,它稍后会返回值(或者我可能不明白?)。所以它必须在函数getValue()中计算。

更新

P.S。那么如何重构我的代码才能在success:处理程序中使用回调?以下是代码的第二部分:

MyClass123.prototype.myMethod = function(value) {
      //..............
      var var1 = this.getValue("key1");
      if (var1 == "123") { ... }
      else { .... }
      //..............
    }
  };

3 个答案:

答案 0 :(得分:8)

请参阅下面的后续行动

可以使ajax请求同步,但这通常是一个坏主意(并且jQuery不会再支持它了。)

相反,让getValue接受回调:

function getValue(key, callback) {
   switch(_options.myType){
     case "cookie":
       setTimeout(function() {
           callback(readFromCookie(key));
       }, 0);
       break;
     case "localStorage":
       setTimeout(function() {
           callback(readFromLocalStorage(key));
       }, 0);
       break;
     case "db":
       //return value from the server
       // how do I wait for the result?
       $.ajax({
           type: "GET",
           url: "123",
           data: { .... },
           success: function(data){
              callback(data);
           }
       });
       break;
   }
}

请注意,我正在setTimeoutreadFromCookie回调使用readFromLocalStorage。为什么?因为如果getValue 可能异步返回其值,那么总是这样做。使用超时0要求浏览器尽快将控制权返回给浏览器(尽管它通常被限制在不低于5-10毫秒)。


重新评论以下内容:

  

你读过我写的东西吗?我说我出于某种原因不能这样做。

我错过了这一点,但在充分尊重的情况下,你可以。它可能需要对代码进行一些重构,但是可以执行它,并且应该。这就是现代Web应用程序的工作方式。如果您的结构不支持它,则需要修复结构。您可以在请求中使用async: false作为临时解决方法,直到您可以正确执行。 (嘿,我们都去过那里,不得不做那样的事情。)请注意,它计划在很长时间内退役(只需jQuery支持它,你仍然可以直接使用XHR来做同步请求)。


更新您的更新问题,以下是更新该代码的方法:

MyClass123.prototype.myMethod = function(value) {
  this.getState("key1", function(var1) {
    //                           ^--- Note the var becomes an arg
    if var1 == "123"{ ... }
    else { .... }
  });
};

请注意它实际变化的程度。用于跟随调用getState的逻辑将转入您传入其中的回调。

答案 1 :(得分:2)

您可以通过指定async: false - 来使AJAX请求同步,这是不推荐但可能的。 如果绝对是您的{{1}在AJAX请求返回之前,函数不应该返回,然后getValue()就可以了。

async

使用$.ajax({ type: "GET", url: "123", async: false // NEW data: { .... }, success: function(data){ value = data; } }); then的替代方案:

when

并且您在其中调用它,请将其命名为:

function getValue(key, callback) {
   switch(_options.myType){

     ...

     case "db":
       return $.ajax({ // note the 'return'
           type: "GET",
           url: "123",
           ...
       });
   }
}

答案 2 :(得分:2)

正确的做法是重构您的程序流,以便您可以将您的逻辑放在success处理程序中。

您可以使用async选项使Ajax请求同步,但这很愚蠢。它会降低你的应用程序的速度,因为浏览器窗口会冻结,直到请求成功(或超时)。它并不经常用于JavaScript开发,而且有充分的理由。