【问题标题】:Returning values from the event onreadystatechange in AJAX [duplicate]从AJAX中的onreadystatechange事件返回值[重复]
【发布时间】:2023-03-10 16:25:01
【问题描述】:

我正在尝试在下面的代码中为变量val 赋值:

var cmdValue = "/cmd/fetch?x=";
var val;
var returned_data;

function what(){
    val = update('#TAG#');
}


function update(tag) {
    var req1 = newXMLHttpRequest();
    req1.open("GET",cmdValue + tag, true);
    req1.send("");

    return req1.onreadystatechange= function () {
        if (req1.readyState == 4 && req1.status == 200) {
            returned_data = req1.responseText;
            return returned_data;
        }else{

        }
    };
}

我在 Firebug 中跟踪变量,结果发现 val 被分配了函数。有没有办法让代码运行,然后将值分配给变量val

【问题讨论】:

  • 因为val是一个全局变量(现在不太推荐),你可以这样做var = returned_data;
  • 我将 val 保留为全局变量,以便在 firebug 中跟踪它。你的意思是 val=returned_data 吗?
  • 是的,对不起,我的意思是val = returned_data
  • ajax 请求是否在通过其余代码之前等待响应。如果没有,那么您的建议将不起作用。

标签: javascript jquery ajax


【解决方案1】:

在异步编程中,您不要 return 数据,因为您不知道该数据何时可用 - 它是异步的。

进行异步编程的方法是使用事件和/或回调。

例子:

var cmdValue = "/cmd/fetch?x=";
var val;
var returned_data;
var performSomeAction = function(returned_data) {
    val = returned_data;
}

function what(){
    update('#TAG#', performSomeAction);
}


function update(tag, callback) {
    var req1 = new XMLHttpRequest();
    req1.open("GET", cmdValue + tag, true);
    req1.send("");

    req1.onreadystatechange= function () {
        if (req1.readyState == 4 && req1.status == 200) {
            returned_data = req1.responseText;
            //fire your callback function
            callback.apply(this,[returned_data]);
        } else {

        }
    };
}

这个问题是关于 SO 的最常见问题之一,至少在涉及到 javascript 标记时 - 请在提出自己的问题之前搜索类似问题。

【讨论】:

  • 对于 js 的新手来说非常困难,因为我从来不知道正确的关键字。是的,我已经找到了一个类似的问题。不过还是谢谢。
  • 如果我正在使用同步代码(open 的最后一个参数为 false)怎么办?
  • @Niko 你永远不应该将async 参数设置为false。这将锁定浏览器,直到服务器响应。始终使用适当的异步技术。
  • 这在用户想要查看内容的典型浏览器应用程序中可能是一个问题,但在不同的上下文中它可能有意义。我猜你可以将你的回调函数传递给“更新”函数,并在收到响应时调用它。
  • @Niko - 同步调用永远不会有意义,因为在请求完成之前无法向用户提供锁定浏览器 UI 和反馈。让我们假设他们的 Wifi 下降了一秒钟 - 我的浏览器崩溃了吗?当我点击任何东西时,界面没有提供任何反馈,甚至没有显示(动画)加载器 - 整个 UI 都被冻结了?我需要CTRL+ALT+DELETE吗? Synchronous XMLHttpRequests = always bad,句号。
【解决方案2】:
// should have a space after new or was did u notice it 
var req1 = new XMLHttpRequest();

【讨论】:

  • 抱歉有一个对象/函数叫做newXMLHttpRequest
  • 该函数只是检查浏览器是否为 IE,然后创建 XMLHttpRequest 对象。
猜你喜欢
  • 2015-11-19
  • 1970-01-01
  • 2016-09-10
  • 1970-01-01
  • 2018-10-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-04-01
相关资源
最近更新 更多