如何在Javascript中将数据返回到原始调用函数?

时间:2009-07-07 20:35:26

标签: javascript jquery ajax callback return

我在将数据返回到我希望它返回的函数时遇到问题。代码如下:

function ioServer(request_data, callback)
{
    $.ajax({
        cache: false,
        data: "request=" + request_data,
        dataType: "json",
        error: function(XMLHttpRequest, textStatus, errorThrown){},
        success: function(response_data, textStatus){
            callback(response_data);
            },
        timeout: 5000,
        type: "POST",
        url: "/portal/index.php/async"
    });
}   

function processRequest(command, item, properties)
{
    var request = {};
    request.command = command;
    request.item = item;
    request.properties = properties;
    var toServer = JSON.stringify(request); 
    var id = ioServer(toServer, processResponse);
    return id;
}

function processResponse(fromServer)
{
    if (fromServer.response == 1)
    {
        return fromServer.id;   
    }   
}

我通过调用另一个函数中的processRequest函数来调用这段代码。发送请求和检索响应工作正常。但是,我需要将响应中的值'id'返回给processRequest函数,因此它可以将该值返回给它的调用者。据我所知,processResponse中的返回值返回$ .ajax,但是我需要它返回到processRequest。

BTW processResponse中的if语句是指服务器端PHP脚本设置的值,用于判断是否允许该请求(例如,如果用户未登录,则fromServer.response将为0)。它与$ .ajax对象的成功/错误例程没有任何关系。

非常感谢你的帮助。

@Jani:谢谢你的回复,但是你能澄清一下吗?需要'id'的函数具有以下代码:

$(#tabs).tabs('add', '#tab-' + id, 'New tab');

你是说我应该尝试在processResponse函数中执行这段代码吗?因为那不是我打算做的;这些功能旨在成为维护状态服务器端的通用解决方案。这就是我避免在那里放置这段代码的原因。

5 个答案:

答案 0 :(得分:5)

我想也许这更接近你所寻找的......

function ioServer(request_data, callback)
{
    $.ajax({
        cache: false,
        data: "request=" + request_data,
        dataType: "json",
        error: function(XMLHttpRequest, textStatus, errorThrown){},
        success: function(response_data, textStatus){
                processResponse(response_data, callback);
                },
        timeout: 5000,
        type: "POST",
        url: "/portal/index.php/async"
    });
}   

function processRequest(command, item, properties, callback)
{
    var request = {};
    request.command = command;
    request.item = item;
    request.properties = properties;
    var toServer = JSON.stringify(request); 
    ioServer(toServer, callback);
}

//internal callback to handle response code
function processResponse(fromServer, callback)
{
    if (fromServer.response == 1)
    {
        //call the callback with the id
        callback(fromServer.id);   
    }   
    else
    {
        //You have to remember to call the callback no matter what
        //or the caller won't know when it's complete
        callback(null);  //or some other "didn't get a valid response" value
    } 
}

答案 1 :(得分:3)

由于这是一个异步请求,因此它不会直接返回类似的值,但这是不可能的。

解决这个问题的方法是使用一些方法对获取的数据执行所需的任何操作,而不是尝试使用不起作用的返回值。

答案 2 :(得分:3)

由于Tony没有提供任何评论,请允许我添加有关他的建议的详细信息。

正如您所了解的那样,只要进行$ .ajax调用,processRequest函数就会完成,因为$ .ajax方法是异步的。那么如何通知processRequest的调用者该任务已完成?

简单,你要求processRequest的调用者提供'回调函数'。只要收到ajax输出,processRequest就会调用此函数。在tony的代码中,这是processRequest函数的最后一个参数。

所以你的调用代码现在看起来像

function tabMethod()
{
     processRequest('command', 'item', 'properties', 
                  function(id)
                  {
                     if(id == null) 
                     {
                          alert('There is a problem!');
                          return;
                     }
                     $('#tabs').tabs('add', '#tab-' + id, 'New tab');
                  });


};

答案 3 :(得分:1)

真棒!谢谢你们的帮助,它现在就像一个魅力。而且我学会了更好地使用回调。这是完整的工作代码:

createTab('#tabs'); // I'm using JQuery UI to handle tabs    

function createTab(parent_element){
            var name = {};
            name.name = "New tab";
            var position = {};
            position.position = $(parent_element).tabs('length') + 1;
            var properties = new Array();
            properties[0] = name;
            properties[1] = position;
            processRequest(1, 1, properties, 
                      function(id)
                      {
                         if(id == null) 
                         {
                              alert('There is a problem!');
                              return;
                         }
                         $('#tabs').tabs('add', '#tab-' + id, 'New tab');
                      });
        }

function ioServer(request_data, callback)
{
    $.ajax({
        cache: false,
        data: "request=" + request_data,
        dataType: "json",
        error: function(XMLHttpRequest, textStatus, errorThrown){},
        success: function(response_data, textStatus){
                processResponse(response_data, callback);
                },
        timeout: 5000,
        type: "POST",
        url: "/portal/index.php/async"
    });
}   

function processRequest(command, item, properties, callback)
{
    var request = {};
    request.command = command;
    request.item = item;
    request.properties = properties;
    var toServer = JSON.stringify(request); 
    ioServer(toServer, callback);
}

//internal callback to handle response code
function processResponse(fromServer, callback)
{
    if (fromServer.response == 1)
    {
        //call the callback with the id
        callback(fromServer.id);   
    }   
    else
    {
        //You have to remember to call the callback no matter what
        //or the caller won't know when it's complete
        callback(null);  //or some other "didn't get a valid response" value
    } 
}

它在页面的列表末尾添加了一个新选项卡。现在,这也是使用PHP和MySQL存储在服务器端,就像我想要的那样。

再次感谢!

答案 4 :(得分:0)

不要像其他人之前发布的那样实现阻塞来模拟同步调用,只需让AJAX调用本身同步并更新您的成功包装器:

function ioServer(request_data, callback) {
    var response = null;
    $.ajax({
        cache: false,
        data: "request=" + request_data,
        dataType: "json",
        error: function(XMLHttpRequest, textStatus, errorThrown){},
        success: function(response_data, textStatus) {
                response = callback(response_data);
        },
        timeout: 5000,
        type: "POST",
        url: "/portal/index.php/async",
        async: false
    });

    return response;
}

编辑:虽然很有用,但这与“普通”AJAX使用方法相悖。我建议改变你的做法。