2012-06-10 21 views
15

我遇到$ .get函数的问题。 URL中包含JSON使AJAX“get”函数同步/如何得到结果?

我的代码:

xyz = null 

    $.get('http://www.someurl.com/123=json', function(data) { 
     var xyz = data.positions[0].latitude; 
    }); 

alert(xyz); 
//some more code using xyz variable 

我知道,因为$.get异步xyz会提醒空的结果。

那么有没有什么办法可以使用xyz以外的这个获取函数?

+0

如果您将'var'关键字移出函数并且在你的初始'xyz'前面,那么你可以在你的ajax请求完成后执行的任何函数中在该范围内的任何地方使用它。 – Paulpro

+4

虽然* * **同步** AJAX(在jQuery中记录*),但通常应该避免*,因为它对用户体验有负面影响。相反,请专注于使用基于事件的异步AJAX模型。也就是说,在回调中用'xyz' *更新DOM。 – 2012-06-10 22:44:40

+0

@pst。一直都有同样的问题。这一个和DOM准备好的问题。 – gdoron

回答

7

真正的答案是NO ,但你可以这样做:

function useXYZ(){ 
    alert(xyz); 
} 

xyz = null   

$.get('http://www.someurl.com/123=json', function(data) { 
    xyz = data.positions[0].latitude; 
    useXYZ(); 
}); 
+0

为什么浪费时间和精神混乱的全球性财产? (或闭合变量)。通常最好写成'function useXYZ(xyz){..}'...然后通过回调中的数据。 – 2012-06-10 22:47:10

+0

@pst。我想这样做,但我想告诉他如何使用外部变量。 (顺便说一句,它不一定是一个全局变量)。您可以根据需要编辑先生! – gdoron

+0

谢谢!认为它适用于警报,我仍然遇到了脚本的其余部分。实际上,当我必须在函数useXYZ(){...} – Diolor

22

get是一条捷径。你可以这样做,但同步,使用:

var xyz = null 


$.ajax({ url: 'http://www.someurl.com/123=json', 
     async: false, 
     dataType: 'json', 
     success: function(data) { 
       xyz = data.positions[0].latitude; 
      } 
     }); 


alert(xyz); 

你必须申报AJAX调用之前xyz变量,虽然。

+0

中放入很多东西时,我诚实地说,我的初始答案很差。我应该停止尝试回答我手机中的问题。 – HackedByChinese

+0

在Chrome和Firefox中,我仍然收到null。在safari中效果不错 – Diolor

+0

嗯。我已经使用Safari,Chrome和Firefox(在OSX上)进行了测试。这里还有一个纯粹的示例http://jsfiddle.net/HackedByChinese/F2Ey5/1/ – HackedByChinese

4

这是Javascript的常见问题。 Javascript代码必须以连续传递方式编写。它的烦人,但它的东西,你可以转换,而不用想太多。

Basicaly,每当我们会碰到这样的

var x = someSyncFunction(a, b, c); 
//do something with x 
console.log(x); 

我们可以将它通过使所有的代码的函数返回到一个连续函数之后和可变转向x转换的参数转换成异步代码继续回调。

someAsyncFunction(a, b, c, function(x){ 
    //do something with x; 
    console.log(x); 
}); 

你必须小心,它很容易写易混淆的代码。要牢记的一个好方法是你可以让自己的函数也接收回调。这使得他们可以使用不同的功能(就像正常的同步助手函数返回值可以通过不同的功能使用)

var getXyz = function(onResult){ //async functions that return do so via callbacks 
           //you can also another callback for errors (kind of analogous to throw) 
    $.get('http://www.someurl.com/123=json', function(data) { 
     var xyz = data.positions[0].latitude; 
     onResult(xyz); //instead of writing "return xyz", we pass x to the callback explicitely. 
    }); 
}; 

getXyz(function(xyz){ //this would look like "var xyz = getXyz();" if it were sync code instead. 
    console.log('got xyz'); 
}); 

这里的技巧是改变从函数的所有return语句到来电来回调函数。认为异步函数永远不会返回,将值返回给某人的唯一方法是将该值传递给回调函数。


你可能会问,为什么没有更简单的方法来做到这一点。那么,除非你使用另一种语言,而不是Javascript(或者至少可以让你在同步风格中编写异步代码,但是会自动编译为常规Javascript)

+0

谢谢!如果我必须从JSON中抓取两个变量,例如纬度为“xyz”,长度为“abc”,那么该怎么办? onResult将如何和函数(xyz)。我可以将它们嵌套在里面还是应该创建第二个函数(abc)? – Diolor

+0

你可以在单个对象中打包两个值,并将对象传递给回调'onResult({lat:xyz,long:abc});',类似于你如何从同步函数返回多个值),或者你可以回调函数接收两个参数而不是一个'onResult(xyz,abc);'。对于不同且互斥的计算路径,通常具有多于一次的回调。一个常见的例子是有一个成功(或“返回”)回调和一个错误(或“抛出”)回调。 – hugomg