AJAX异步调用 - 无法使用回调返回数据?

时间:2013-02-06 15:03:07

标签: jquery ajax callback

我在下面有这个代码,我想在ajax调用的success函数中返回数据。当然,如果我做async:false并直接返回它我得到它但我不想那样做。

如果我像现在一样运行它,信息变量是未定义的(如果我执行async:false,它会获取信息,因此不是数据的内容是问题)。

我只是不明白为什么它不起作用,我用谷歌搜索回调函数,看起来我做得对...

function PUT_updateSystem(id) {
    var system= {};
    system= getSystemInformation(name, function(data){
                                var system = data;
                                return system;});

    var information = system.info;

}
// Returns system information
function getSystemInformation(name,callback){
    $.ajax({
        type:"GET",
        url: getUrl(),
        cache: false,
        dataType: "json",
        success: function(data){
            callback(data);
        }
    });
}

编辑: 将我的代码更改为我目前的代码

我正在使用这些数据生成一个jsTree,并为该树创建json数据,我正在进行上述操作,但是将信息变量放入一个对象并迭代它以创建节点。问题不在于树,所以我不会在这里包含它。我甚至可以把这个逻辑用于测试。

所以发生了什么,

  1. 页面开始加载
  2. 我执行上述
  3. 信息被放入javascript对象
  4. 我遍历javascript对象。
  5. 我收到错误“无法读取未定义的属性'长度”
  6. 正在调试时,我发现它跳过了system.done。这是有道理的,因为它可能无法完成。
  7. 有没有办法等待它完成?

    编辑: 提供更多信息

      

    //在一个文件中调用loadinfo.js

    // Returns system information promise
    function getSystemInformation(){
        return $.ajax({
            type:"GET",
            url: getUrl(), // url is defined somewhere else
            cache: false,
            dataType: "json"
        });
    }
    
    // IN A FILE CALLED tree.js
    // I have other variables from loadinfo.js that are here so they can communicate fine
    
        $.when(getSystemInformation(), $.Deferred(function(deferred) {
            $(deferred.resolve);
        })).done(function(data) {
            mapCache["system"] = data;
            console.log("defer DONE!!");
    
    $.each(mapCache["system"], function(index, system) {
                var children = doDisplayChildNodes(system.name);
                ...
                        ...
    });
    

    我在这个$ .each中正在做的只是从mapCache [“system”]中获取数据并创建一个“jstree”节点。我做一个子函数来做同样的事情,因为我有与每个系统相关的子节点。所有这些逻辑都有效,因为当我将ajax调用称为“async:false”时它工作正常 - 所以我不会发布它。

    我在$ .each中收到了未读取的未定义属性'length'。这很奇怪,因为我在mapCache上设置了“Watch”,并且在加载完所有内容后,mapCache将填充正确的值。我正在使用Google Chrome调试。

4 个答案:

答案 0 :(得分:5)

您使用了回调,但仍然使用同步逻辑而不是异步。试着这样做:

function PUT_updateSystem(id) {
    var system = getSystemInformation(name);
    system.done(function(data){
        var information = data.info;
        // do stuff with `information` here, not elsewhere.
    });
}
// Returns system information promise
function getSystemInformation(name){
    return $.ajax({
        type:"GET",
        url: getUrl(),
        cache: false,
        dataType: "json"
    });
}

答案 1 :(得分:0)

function PUT_updateSystem(id) {
    var system= {};
    system= getSystemInformation(name, callbackfunction);

    var information = system.info;

}
//callbackfuncion
function callbackfunction(data){
    var system = data;
    return system;
}
// Returns system information
function getSystemInformation(name,callback){
    $.ajax({
        type:"GET",
        url: getUrl(),
        cache: false,
        dataType: "json",
        success: function(data){
            window[callback](data);
        }
    });
}

而不是callback(data);
window[callback](data);
并将函数名称作为变量

答案 2 :(得分:0)

Asynchronyous意味着在PUT_updateSystem完成后调用回调。

当你调用getSystemInformation时,会向服务器发出请求,但是在调用函数后,会立即向var information = system.info;在服务器有时间响应之前system.info;尚未设定。如果你有一个带有开发者工具IE浏览器的浏览器,带有firebug插件的Firefox,Chrome你需要做的就是按F12。并运行以下代码,您可能会理解回调意味着在控制台中查看消息(警报不起作用,因为它会暂停JavaScript执行。

function PUT_updateSystem(id) {
    var system= {};
    system= getSystemInformation(name, function(data){
                                var system = data;
// you re declare system here so it' actually not set
// if you want to set system in PUT_updateSystem you should
// do system = data; without the val
console.log("this comes last");
console.log("data is returned now",data);
                                return system;});
console.log("This comes first");
    var information = system.info;

}
// Returns system information
function getSystemInformation(name,callback){
    $.ajax({
        type:"GET",
        url: getUrl(),
        cache: false,
        dataType: "json",
        success: function(data){
console.log("this comes second");
            callback(data);
        }
    });
}

答案 3 :(得分:-2)

你做得不对,回调不会返回任何数据。 JavaScript中没有等待语句。执行异步调用,并且JavaScript继续处理其余代码。

您的代码应为

function PUT_updateSystem(id) {
    var system= {};

    function processData(data) {
        var information = data.info;
        alert("Do next step");
    }

    system = getSystemInformation(name, processData);
}

将你的逻辑分成两步。

  1. 进行Ajax调用
  2. 处理回叫中的数据