3

可能重复:
是否可以在它之外使用 ajax 响应?

我创建了以下 JavaScript 例程,该例程转到 WCF oData 服务并获取一些数据。在成功元素中,我将结果放入结果变量并提醒他们 - 我看到有返回的对象。当我在 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;
}

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

编辑

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

4

4 回答 4

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)。所以无论如何你都必须使用回调。

于 2012-06-26T10:59:43.017 回答
5

理查德的同胞!

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

于 2012-06-26T10:57:10.397 回答
1

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

但是,jQuery 文档说:

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

于 2012-06-26T10:56:28.870 回答
1

发送 AJAX 请求,脚本无需等待响应,这就是 Dave Newton 的意思A-synchronus,将警报放在成功回调函数中,您将看到实际响应是什么。

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

于 2012-06-26T10:58:21.760 回答