簡體   English   中英

數組元素存在但不存在

[英]Array element is there but it isn't there

  1. 在輸入字段中收聽“Keyup”
  2. 將“enableSubmitButton”定義為數組
  3. 做點事
  4. 將數組元素添加到“enableSubmitButton”數組
  5. 從當前輸入字段我搜索父表單,然后我循環所有輸入字段
  6. 在這個循環中,我向服務器發出請求
  7. 在“onreadystatechange”函數中,我將另一個元素推入“enableSubmitButton”數組

問題是,我在“onreadystatechange”中推送的元素實際上並不在數組中。 當我使用console.log()查看數組時,元素是可見的,但是如果我使用“array.length”函數,則不包括數組元素:-O

$('.checkEmail, .checkPwd, .checkPwdC').bind("keyup", function() {
    //define enableSubmitButton as an array
    var enableSubmitButton = [];

    //loop each input field in the form
    $(this).parents("form").find(":input").each(function(index,data){

        //do some "if then else" and other stuff
        ...
        enableSubmitButton.push(true);
        ...

        // Now I make a request to the server with Ajax
        var xmlhttp = new XMLHttpRequest();                                
        xmlhttp.onreadystatechange = function() {
            if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
                if(xmlhttp.responseText == "doesntExist"){
                    enableSubmitButton.push(true);
                }else{
                    enableSubmitButton.push(false);
                }
            }
        };

        //Request
        xmlhttp.open("GET", "ajax.php?ajaxCase=cuna&userName="+$('#fNewAccount input.checkAvailability').val(), true);
        xmlhttp.send();
    });

    // PROBLEM
    // and here we have the problem. To debugg, i use the console.log() function as follow
    var okForSubmit = true;

    console.log(enableSubmitButton);
    console.log("array length: "+enableSubmitButton.length);

    for(var i = 0 ; i < enableSubmitButton.length ; i++){
        if(enableSubmitButton[i] == false){
            okForSubmit = false;
        }
        var newTime = Math.floor(Math.random() * (100 - 1 + 1)) + 1;
        console.log(i+" - "+enableSubmitButton[i]+" - "+newTime+" - "+okForSubmit);
    }
});

這是 console.log() 輸出:

(4) [true, true, true, true]
0: true
1: true
2: true
3: true
4: false
length: 5
__proto__: Array(0)

array length: 4
0 - true - 54 - true
1 - true - 19 - true
2 - true - 51 - true
3 - true - 94 - true

有任何想法嗎?

這只是 JavaScript 控制台本身:它記錄活動對象和文本的混合:

stuff=[true];
console.log(stuff);
stuff.push(false);

如果您在 JavaScript 控制台中執行此操作,您將看到類似

> (1) [true]

這來自日志,在推送之前。 但是如果打開“>”部分,它會顯示對象的當前狀態,包括推送的結果:

(1) [true]
 0: true
 1: false
 length: 2

所以(1) [true]部分只是文本,它不會更新,但是當你“打開”它的細節(使用小箭頭)時,對象會被評估。 如果您再次推送某物,則什么都不會改變(當然在屏幕上),但是可以使用關閉-重新打開詳細信息來再次評估對象,等等。

這是一個典型的異步問題:HTTP 請求只會在您的所有其他代碼運行完畢后才會與響應(調用回調)一起出現。

控制台顯示數組中的元素是一種誤導,但那是因為控制台只接收數組的引用,一旦你查看它,HTTP響應已經被處理了,所以你看到了數組中的內容安慰。

執行console.log調用時真正查看數組內容請像這樣序列化數組:

console.log(JSON.stringify(enableSubmitButton));

現在你會看到它實際上是空的。

為了解決基本問題,您可以利用 jQuery 為它公開的 Ajax 方法返回的承諾(無論如何它比httpRequest更容易使用)。 然后你首先將所有這些承諾收集在一個數組中,然后對它們調用$.when 這個$.when調用的回調只有在您收到所有 Ajax 響應后才會執行,只有這樣您才能安全地創建您的enableSubmitButton數組。

這是一個簡化的概念證明:

 $('button').click(function f(e) { e.preventDefault(); var $inputs = $(this).parents("form").find(":input"); var promises = $inputs.map(function(index, data){ // Make your request with jQuery, which returns a promise // I use a test URL here; replace with your own var url = "https://jsonplaceholder.typicode.com/posts/" + (index+1); return $.get(url).then(function(response) { return response == "doesntExist"; // a boolean }); }).get(); // array of promises // When all promises have resolved, only then get your array $.when.apply($, promises).then(function () { // Get the arguments -- which are the values returned by the `then` callbacks: var enableSubmitButton = [].slice.call(arguments); console.log('result', enableSubmitButton); }); });
 <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <form> <input value="100"><input value="abc"> <button>Click me</button> </form>

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM