这是JavaScript / JQuery中的范围问题吗?

时间:2012-06-26 10:53:05

标签: javascript jquery

  

可能重复:
  Is it posible to use ajax respone outside of it?

我创建了以下JavaScript例程,该例程转到WCF oData服务并获取一些数据。在success元素中,我将结果输入结果变量并提醒它们 - 我看到有返回的对象。当我在ajax调用之外运行第二个警报并且在返回结果之前,结果变量是“未定义的”。

任何人都可以告诉我哪里出错了吗?

function retrieveJsonpODataSet(baseUrl, query)
{
  var oDataUrl = baseUrl + "?$format=json&$callback=?";
  var results;

  $.ajax(
  {
    url: oDataUrl,
    contentType: 'application/json; charset=utf-8',
    type: 'GET',
    dataType: 'jsonp',
    async: false,
    success: 
      function (data, textStatus, xhr) 
      {
          results = data.d;
          alert(results);  // This shows the results
      },
    error: 
      function (xhr, textStatus, errorThrown) 
      { 
          alert("Query failed.\n\n" + oDataUrl + "\n\n" + errorThrown);
          results = null;
      }
  });
  alert(results);  // This shows "undefined"
  return results;
}

请忽略查询参数 - 我还没有完成例程。

修改

最初我在ajax调用中没有async:false。我现在已经添加了,但它无法解决问题。

4 个答案:

答案 0 :(得分:6)

ajax调用是异步操作。它会触发,你的代码也不会停止。因此返回results,此时未定义。你需要做的是将回调传递给函数。

function retrieveJsonpODataSet(baseUrl, query, callback) {
   /* some code */
   $.ajax({
       /* some settings */
       success: function(res) {
           /* some code */
           callback(results);
       }
   });
}

现在你像这样使用它

retrieveJsonpODataSet(baseUrl, query, function(res) {
    /* Hurray, I have result now in res variable! */
});

请勿使用async: false选项!它会阻止所有脚本,直到调用结束......如果它根本没有完成怎么办?你将永远被封锁。

修改

我错过了请求是JSONP。在这种情况下,async: false甚至不起作用(它不适用于跨域请求和JSONP)。所以你必须使用回调。

答案 1 :(得分:5)

理查德的同事!

这不是范围问题,而是更多的执行问题。 successerror选项都是事件处理程序,并且是异步运行的(因此它被称为AJAX)。这实际上意味着alert(results)return results可以,并且可能会在触发successerror事件之前执行。

答案 2 :(得分:1)

您的ajax是异步的,因此警报会在ajax完成之前执行。您需要将ajax调用async属性设置为false,以便脚本暂停执行,直到发出ajax请求为止。处理。

然而,jQuery文档说:

异步 默认值:true 默认情况下,所有请求都是异步发送的(默认设置为true)。如果需要同步请求,请将此选项设置为false。跨域请求和dataType:“jsonp”请求不支持同步操作。请注意,同步请求可能会暂时锁定浏览器,并在请求处于活动状态时禁用任何操作。 从jQuery 1.8开始,不推荐使用async:false。

答案 3 :(得分:1)

发送AJAX请求,而脚本没有等待响应,这就是Dave Newton在A-synchronus中的含义,将警报置于成功回调函数中,您将看到实际响应是什么。

或者,您可以指定async属性,并将其设置为false,以强制您的脚本等待响应,然后再继续。