2011-06-13 108 views
4

我不清楚以下啞代碼的返回值:javascript函數的返回值混淆

function foo() 
    var ret = 0; 
    var xhr=send_request("bla", function() { 
     // do something with the AJAX response 
     // based on the value of response, var ret get set 
    }); 
    return ret; 
} 

我想實現的是:基於AJAX的反應,我可能會決定嘗試請求再次。但是上面的函數總是返回0。

顯然我可以讓foo()函數在需要時決定調用send_request()兩次,但它有點難看。有沒有一個簡單而好的方法來做到這一點?

感謝

+0

什麼是'foo'返回?可以在'send_request'中訪問嗎? – Jeremy 2011-06-13 15:12:43

+0

您的ajax回調函數被異步調用,因此ret永遠不會被設置爲不同的東西。未命名函數的範圍不在foo()中,而是在本地。 – venimus 2011-06-13 15:15:29

回答

7

您正在嘗試使AJAX調用同步的,但你是一個做的異步調用。

重要的是要明白,你寫的方式,代碼不會等待AJAX​​調用完成,然後再轉到下一行。因此,它始終返回初始值ret

做幾件事情來解決這個問題:

  • 使用jQuery(如果你沒有的話)
  • 使用jQuery的ajax()功能,並設置async爲false。

應該是這個樣子:

function foo() 
    var ret = $.ajax({ url: "blah", 
         async: false 
        }).responseText; 

    // do your stuff here 

    return ret; 
} 

編輯:這是可能的異步調用做到這一點,但你要調整你思考問題的方式。不要考慮返回值,你必須考慮回調函數。

爲了舉例,我們可以說我試圖獲取用戶名並將其放在頁面上。我的代碼看起來是這樣的:

function GetUsername() { 
    $.ajax({ url: "blah", 
       success: PopulateUsername // Specify a callback 
      }); 
    // I don't do anything else. Execution will continue when the 
    // callback gets called from the AJAX call. 
} 

function PopulateUsername(data) { 
    alert(data); 
    // Anything else I want to do, I do here, because it is only 
    // here that I have access to the result. 
} 

GetUsername(); // I call GetUsername() here, and that's it. Any 
       // further actions that need to happen are going to 
       // occur in the callback function 
+0

謝謝。除了使AJAX請求同步外,還有其他方法嗎? – lang2 2011-06-13 15:22:02

+2

是的,但它涉及重構你的代碼(並調整你對事物的思考方式)。我會快速編輯。 – riwalk 2011-06-13 15:23:47

+0

在一個例子中使用'document.write'並不是很好,尤其是當Ajax請求完成時完整的DOM樹會被清除。 – 2011-06-13 15:33:13

0

變量ret在函數中有一個局部作用域。因此,在每次調用時,變量被初始化爲0

而且,當函數返回變量ret,在send_request函數(設置別的東西ret)尚未運行,由於該值返回值始終爲0.它必須在返回的函數完成後,ajax請求完成並且send_request函數將一個新值設置爲ret

0

如果你想保持同步的東西,然後使用Stargazer712的建議。

你可以試着讓事情異步像這樣的東西:

function foo(callback) 
    var xhr=send_request("bla", function(result) { 
    callback(result) 
    }); 
} 


function test(result) { 
    // test result here 
    if(result != "what I want") 
    foo(test); // repeat the ajax call under certain conditions 
    else 
    alert("got it"); 
} 


$(function() { 
    foo(test); 
}); 

直到響應相匹配的一定值這將重複Ajax請求。

+0

我發現AJAX調用失敗的一個常見原因是,如果您位於網站的經過身份驗證的部分並且會話過期。如果是這種情況,這將導致無限循環。注意以這種方式編寫代碼。 – riwalk 2011-06-13 15:37:03

+0

是的,這不是爲了媚態:) – Nathan 2011-06-13 18:17:57

0

你不想從一個函數返回一個值來進行AJAX調用,因爲AJAX請求在函數返回之前還沒有完成(並且我個人不同意那些說你應該設置異步的答案假)。你想這樣做,而不是:

function retFunction(val) { 
    // Do something here for various values of val 
    if (val == 0) { 
    // Something 
    } else if (val == 1) { 
    // Something else 
    } 
} 

function foo() 
    var xhr=send_request("bla", function() { 
    var myResult = 0; // Something here based on return values. 
    retFunction(myResult); 
    }); 
}