在JavaScript中等待Json调用完成

5
我在我的JavaScript方法中使用以下的 JSON 调用。
function go123(){
    var cityName = "";
    var temp = $.getJSON("https://abc.in/api/city?callback=?", args,function (data) {
        if (data.properties.city != null){ 
            cityName = data.properties.city;
            check = true;
        } else {
            cityName = "NaN"
        }
    }); // end of my Json Call.

    // my validation is done below
    if(cityName != "NaN"){
        return false;
    } else {
    // here I except the cityName to not be "" but be some value which  is set as :cityName = data.properties.city;
        return true;
    }
} // end of my function 

现在我面临的问题是,在我的Json调用完成之前,在代码下面的“//我的验证在下面完成”这行之后,下一组语句已经执行。 我想获得在我的json调用中设置的值(cityName),并且只有在调用完成时才希望执行下一组语句。 请帮助我解决这个问题。任何建议/想法/建议都将不胜感激!谢谢。
4个回答

6
您传递给$.getJSON()的函数是在该函数成功完成时运行的回调函数。一切其他条件相等时,请将“其余部分”放入该方法中。如果您无法这样做,您需要使用jQuery Deferred。请参见http://www.erichynds.com/jquery/using-deferreds-in-jquery/http://joseoncode.com/2011/09/26/a-walkthrough-jquery-deferred-and-promise/,其中代码看起来像这样:
var req = $.getJSON('blah', 'de', 'blah');

req.success(function(response){
    // The request is done, and we can do something else
});

我希望主函数返回“true”或“false”,但在成功方法中似乎无法实现。这是否可能,还是我在编码时犯了错误? - Yasser Shaikh
同步等待异步方法是不好的做法。您的主函数可以返回延迟对象,调用者也可以订阅其完成事件。 - robrich

5

AJAX调用是异步的。它们不等待回复。它们在后台运行,并在调用之后立即执行其后面的代码。因此,在执行其下方操作时,getJSON接收到的数据尚不存在。

您可以将希望执行的操作放在回调函数中,以便在接收到数据时执行它们:

function go123(callback){
    var temp = $.getJSON("https://abc.in/api/city?callback=?", args,function (data) {
        //execute the callback, passing it the data
        callback(data);
    });
}

//when you call go123, it get's back the result:
function goBefore123(){

    //get our JSON
    go123(function(data){

        //when we get our data, evaluate
        if (data.properties.city != null){

            cityName = data.properties.city;
            check = true;

            alert('executed after returned');
            afterCall();
        } else {
            cityName = "NaN"
        }
    });

    alert('i am executed before anything else');
}

function afterCall(){
    alert('im also executed after');
}

你写在函数外面的 go123(function(result)) 是什么?它需要以分号结尾吗? - Yasser Shaikh
@Yasser,go123(function(result){...}) 调用了 go123() 函数,并传递了一个“回调”函数作为参数。一旦 getJSON 收到响应,该回调函数将被执行。是的,在调用后应该加上 ;。虽然这是可选的,但为了最佳实践,应该加上。 - Joseph
我理解的是,现在我可以将我的JSON移动到一个名为go123的函数中,然后我可以有另一个函数abc,在其中编写第二组(go123(function(result){})代码,对吗? - Yasser Shaikh
@Yasser 是的,有点像。简单来说,你的“JSON获取器”是 go123。当你需要从中获取数据时,就调用它。如果你想对返回的数据进行操作,可以传递一个回调函数来处理这些数据。 - Joseph
我现在正在使用一个名为goBefore123()的方法,在其中我使用了第二段代码,但我仍然无法从该方法中返回true/false?我可能做错了什么吗? - Yasser Shaikh
让我们在聊天中继续这个讨论:http://chat.stackoverflow.com/rooms/10633/discussion-between-yasser-and-joseph - Yasser Shaikh

3
调用外部 URL 会花费太多时间,请等待结果。请查看以下内容。
var jqxhr = $.getJSON("example.json", function() {
  alert("success");
})
.success(function() { alert("second success"); })
.error(function() { alert("error"); })
.complete(function() { alert("complete"); });

http://api.jquery.com/jQuery.getJSON/


我希望主函数返回“true”或“false”,但在成功方法中似乎无法实现。这是否可能,还是我在编码时犯了错误? - Yasser Shaikh


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接