等待JS函数中异步调用的结束。 (jQuery.Deferred?)

时间:2014-09-20 14:01:23

标签: javascript jquery asynchronous jquery-deferred deferred

这是我的(简单)问题:

我有一个Javascript函数,它调用外部API以异步获取某些结果。我需要等待这些结果,因为我想对它们进行一些测试以确定它们是否有效,但Deferred对我来说非常复杂,我无法成功。

以下是我所做的:

$("#step-content").steps({
    //some parameters
    onStepChanging: function(event, currentIndex, newIndex) {
        verifyAddress().done(function(test) {
            if($("#hdnLatitude").val() == "" || $("#hdnLongitude").val() == "")
                test = false;
            else
                test = true;

            console.log(test); // test is true or false, that's good
            return test;
        });

        console.log(test); // test is always empty here

        //Here, I just need to do return true or return false to block step-changing if there is an error.
        return test;
    }
});

基本上,这是我的verifyAddress功能:

function verifyAddress() {
    var r = $.Deferred();

    var geocoder = new google.maps.Geocoder();
        if (geocoder) {
            var adressToGeocode = /* Get the address to geocode */

            geocoder.geocode({ 'address': adressToGeocode }, function (results, status) {
                if (status == google.maps.GeocoderStatus.OK) 
                {
                    //Save the lat/lng returned in #hdnLatitude and #hdnLongitude
                }

                r.resolve();
            });
        }
    //Not sure where to place the return r ; try elsewhere but no success
    return r;
}

所以我需要的是等待verifyAdress()的结束并填充 #hdnLatitude #hdnLongitude ,并在{{中返回true的false 1}}事件确定我们是否可以进入下一步(地址是正常的)而不是(地址是错误的)

我正在使用this SO question来更好地理解onStepChanging,但我无法成功 有人能帮助我吗?

非常感谢

2 个答案:

答案 0 :(得分:1)

你的功能应该如下:

function verifyAddress() {
    var r = $.Deferred();

    //call Google server to geocode my address. The call is asynchrounous.
    //The results are put in #hdnLatitude and #hdnLongitude fields.
    //The fields are correctly filled.
    googleFunc(someParam, function done(){
      r.resolve();
    });

    return r;
}

你必须在一些将由Google服务器函数调用的done回调中解决延迟,必须有一些回调函数来处理结果。

var test = false; //Can't change step until allowed in async function   
$("#step-content").steps({
    //some parameters
    onStepChanging: function(event, currentIndex, newIndex) {
    if (!test)
      verifyAddress().done(function() {
            if($("#hdnLatitude").val() == "" || $("#hdnLongitude").val() == "")
                test = false;
            else
                test = true;

            console.log(test); // test is true or false, that's good

            //Auto move to next step if test is true
        });


        //Here, I just need to do return true or return false to block step-changing if there is an error.
        return test;
    }
});

答案 1 :(得分:0)

好的,正如@Bergi所说,这个插件似乎不可能。

所以,我绕过了问题,将Next按钮替换为调用我的异步事件的假。在此事件结束时,如果结果正常,我将Next按钮替换为我克隆的orignal,并在其上触发click事件以传递到下一步而无需用户点击两次。

不知道它是否真的很干净,但它能满足我的需求