数组元素在那里,但它不在那里

时间:2017-10-28 15:52:06

标签: javascript arrays

  1. 在输入字段中收听“Keyup”
  2. 将“enableSubmitButton”定义为数组
  3. 做一些事情
  4. 将数组元素添加到“enableSubmitButton”数组
  5. 从当前输入字段中搜索父表单,然后循环所有输入字段
  6. 在此循环中,我向服务器发出请求
  7. 在“onreadystatechange”函数中,我将另一个元素推入“enableSubmitButton”数组
  8. 问题是,我在“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
    

    任何想法?

2 个答案:

答案 0 :(得分:0)

这只是JavaScript控制台本身:它记录了实时对象和文本的混合:

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

如果您在JavaScript控制台中执行此操作,您将看到类似

的内容
> (1) [true]

在推送之前来自日志。但是如果你打开&#34;&gt;&#34;部分,它将显示对象的当前状态,包括push的结果:

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

所以(1) [true]部分只是文本,它不会更新,但是当你打开&#34;对象时会对它进行评估。它的细节(使用小箭头)。如果你再次推送一些东西,当然没有任何改变(当然在屏幕上),但关闭 - 重新打开细节可以用来再次评估对象等。

答案 1 :(得分:-1)

这是一个典型的异步问题:HTTP请求只会在所有其他代码运行完毕后附带响应(调用回调)。

控制台显示数组中的元素是错误的,但这是因为控制台只接收数组的引用,一旦你查看它,HTTP响应已经被处理,所以你看到了控制台中的内容。

console.log

现在你会看到它实际上是空的。

为了解决基本问题,你可以利用jQuery为它公开的Ajax方法返回的承诺(无论如何比console.log(JSON.stringify(enableSubmitButton)); 更容易使用)。然后,您将首先收集数组中的所有promises,然后在它们上调用httpRequest。此$.when调用的回调仅在您收到所有Ajax响应时执行,只有这样您才能安全地创建$.when数组。

这是一个简化的概念证明:

&#13;
&#13;
enableSubmitButton
&#13;
$('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);
    });
});
&#13;
&#13;
&#13;