【问题标题】:Javascript Array undefined? [duplicate]Javascript数组未定义? [复制]
【发布时间】:2013-09-13 17:18:41
【问题描述】:

这似乎是一个可笑的微不足道的问题,但我无法解决。

我有这个功能。 var q 被分配给一个字符串数组。 alert(q)函数调用时成功打印整个数组。

function initQuestions() {
    $.post("quiz.php", { 'func': 'load' }, function(data) {
        var q = data.split(".\n");
        alert(q);
        return q;
    });
}

但是,当我尝试使用该函数时(如下图所示的 2 种方式),我被告知该数组未定义。为什么会这样?

var questions;

$(function() {
    //This doesn't work
    questions = initQuestions();
    alert(questions);

    //Neither does this
    alert(initQuestions());
});

经过进一步研究,我向initQuestions() 添加了回调,但结果相同。

【问题讨论】:

  • 不要尝试提醒它,而是使用console.log()
  • 检查浏览器中的错误日志。你有它是有原因的。并使用 console.log 而不是 alert。
  • 欢迎来到异步 Web 编程的精彩世界
  • 您正在读取设置 var q 之前的值。
  • 从外观上看是范围问题

标签: javascript ajax


【解决方案1】:

post 调用是异步的:Async Javascript

基本上,initQuestions() 函数在 post 完成之前返回 null

这样想:

function initQuestions() {
    $.post("quiz.php", { 'func': 'load' }, function(data) {
        var q = data.split(".\n");
        alert(q);
        return q; // <- returns to the caller of function(data), not initQuestions()!
    });
    return null; // <- This happens before function(data) is complete
}

要使其按预期工作,您需要在发布成功并完成时提供回调。

function initQuestions(callback) {
    $.post("quiz.php", { 'func': 'load' }, function(data) {
        var q = data.split(".\n");
        alert(q);
        callback(q);
    });
}

var questions;

function doSomthingWithQuestions() {
    alert(questions); // <- should work
    // do the things with the questions
}

$(function() {
    initQuestions(function(result) {
       questions = result;
       doSomethingWithQuestions();
    });

    // Don't use `questions` here as the callback hasn't fired yet. 
});

【讨论】:

  • 这解释了为什么它不起作用,但不是 OP 应该怎么做。
  • 谢谢,这行得通,但这是我以前尝试过的,但无济于事。这次让它工作的原因是将函数调用放在 document.ready 的最顶部。为什么将一段代码放在一段不相关的其他代码之后时,一段代码不起作用?
  • 其实我说得太早了。 questions 在回调之外仍未定义
  • 如果您在回调触发之前调用回调之外的代码。如果你想使用 questions 变量,你必须问题加载后使用它
【解决方案2】:
var questions; // undefined right now
initQuestions(function(_questions){
  questions = _questions; // the value has been set thanks to the anonymous function you passed as the callback
})

function initQuestions(callback  // this is a callback function reference) {

  // This HTTP Post call takes time to complete and is done asynchronously
  $.post("quiz.php", { 'func': 'load' }, function(data) {
    var q = data.split(".\n");
    // Luckily your initQuestions now takes in a callback function
    // You have access to the callback function here and when ready you can use it
    callback(q);
  });
  // JavaScript engine doesn't wait for your HTTP call to complete 
  // and will continue to execute the function
  // In this case, your function isn't returning anything hence undefined

}

【讨论】:

  • asynch = false,解决了这个问题,这个解决方案太复杂了
  • 这表示不应该使用 asynch = false stackoverflow.com/questions/14220321/…
  • @kajacx - async false 是 bad 用于用户体验和糟糕的设计决策(它在 ajax 调用期间锁定了浏览器 UI)。它几乎不应该被使用。
  • 是的,锁定很糟糕,但是 OP 询问他的 initQuestions() 函数如何从 ajax 返回数据,否则不能通过 asynch=false 完成
  • “为什么会这样?”是问题。
【解决方案3】:

帖子是异步的,返回的不是你期望的函数,而是成功的处理程序:

function initQuestions() {
  $.post("quiz.php", { 'func': 'load' }, function(data) { // <- this function has that return
    var q = data.split(".\n");
    alert(q);
    return q;
  });
}

here 是如何抑制异步行为并实现你想要的

编辑:

正如这里有些人所说,asych = false 是一个坏主意,因为它会冻结您的 JS 代码,直到请求完成(连接速度慢可能需要几秒钟),所以解决方案是在成功函数中做任何您想做的事情:

questions = initQuestions(); //wrong
fillDivsWithData(questions); //use callback instead:

function initQuestions() {
  $.post("quiz.php", { 'func': 'load' }, function(data) {
    var q = data.split(".\n");
    console.log(q); //diplay this in you browser's JS console
    fillDivsWithData(q);
  });
}

结果是一样的,但是由于异步请求,如果你有土豆互联网连接,你的 JS 代码不会冻结几秒钟。

【讨论】:

猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-11-25
  • 2015-12-12
  • 1970-01-01
相关资源
最近更新 更多