【问题标题】:How does one return data to the original caller function in Javascript?如何在 Javascript 中将数据返回给原始调用者函数?
【发布时间】:2010-11-08 20:17:39
【问题描述】:

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

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。

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

非常感谢您的帮助。

@Jani:感谢您的回复,但您能再澄清一下吗?需要'id'的函数代码如下:

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

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

【问题讨论】:

    标签: javascript jquery ajax callback return


    【解决方案1】:

    我认为这可能更接近您正在寻找的内容......

    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
        } 
    }
    

    【讨论】:

    • 为您的代码建议以及调用代码的外观添加了说明。我希望你不要介意。 stackoverflow.com/questions/1094716/…
    • 如果我想从 ioServer 返回对 processRequest 的响应,并且如果有超过 1 个函数正在调用 ioServer,所以我不确定 Requestee 函数名称 ?????
    【解决方案2】:

    由于 Tony 没有提供任何 cmets,让我添加有关他建议的详细信息。

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

    很简单,你要求 processRequest 的调用者提供一个“回调函数”。 processRequest 将在收到 ajax 输出时调用此函数。在 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】:

    由于这是一个异步请求,所以它不会直接返回这样的值,也不可能。

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

    【讨论】:

      【解决方案4】:

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

      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 的服务器端,就像我想要的一样。

      再次感谢!

      【讨论】:

        【解决方案5】:

        不要像以前发布的其他人那样实现阻塞来模拟同步调用,只需使 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 使用的特点。我建议改为改变你的方法。

        【讨论】:

        • 您不想进行同步调用,因为如果无法快速完成 ajax 请求,它可能会冻结浏览器。
        • @solutionyogi 哈,是的,当您发表评论时,我正在对此进行编辑。但是,我过去(不情愿地)这样做了,没有浏览器冻结问题。据我所知,JavaScript 只是等待/阻塞,不执行任何操作。
        猜你喜欢
        • 2014-10-02
        • 2011-07-26
        • 2021-04-16
        • 1970-01-01
        • 1970-01-01
        • 2010-11-16
        • 1970-01-01
        • 1970-01-01
        • 2011-05-03
        相关资源
        最近更新 更多