Javascript AJAX 函数返回类型未定义

标签 javascript jquery ajax undefined

我遇到了一些 JavaScript 逻辑问题,其中我的函数被返回为未定义,而不是我正在寻找的所需的真/假。我已经尝试了所有可以想象的方法,包括使用回调函数和 JQuery 的不同对象。一旦 AJAX 调用完成,该函数就处于未定义状态(就在 console.log 语句中)。有人可以帮助我吗?

function validateZip(countryCode, zip) {
    // US validation
    if (countryCode == 'US' && /^\d{5}([-\s]?\d{4})?$/.test(zip)) {
        getZipJson(zip).done(function(response){
            return isValid(response.results[0].address_components);
        });
        // international validation
    } else {
        return /^[A-Za-z0-9]{1,5}[-\s]?[A-Za-z0-9]{3,9}$/.test(zip);
    }
}

function getZipJson(zip) {
    var uri = 'http://maps.googleapis.com/maps/api/geocode/json';

    // need to add google api key to data
    return $.ajax({
        type: 'GET',
        url: uri,
        dataType: 'json',
        data: { address: zip }
    }).success(function(response) {
        console.log(response);
    });
}

function isValid(address_components) {
    var resultFound = false;

    $.each(address_components, function (i, component) {
        var types = component.types,
            country = component.long_name;

        $.each(types, function (j, type) {
            if (type == 'country' && country == 'United States') {
                resultFound = true;
                return false; // break out of .each loop
            }
        });

        if (resultFound) {
            return false; // break out of .each loop
        }
    });

    return resultFound;
}

最佳答案

I can get the json data just fine. The issue I am having is that after retrieving the ajax'd json and filtering through the response json, the function is coming back as undefined. I need the function to return a true/false value.

这根本不可能,因为 ajax-rewuest 在 validateZip 被调用甚至返回之后很长时间才做出响应。您必须选择异步编程的两种可能性之一:连续性(又称为回调)或 promise 。 (ES7还引入了关键字async和await,据我所知,它们只是promise的语法糖;就像class关键字只是以更好的方式利用原型(prototype)继承)。

所以,回调风格:

function validateZip(countryCode, zip, callback) {
    if (countryCode == 'US' && /^\d{5}([-\s]?\d{4})?$/.test(zip)) {
        // US validation
        getZipJson(zip).success(function(response){
            callback(isValid( response.results[0].address_components ));
        });
    } else {
        // international validation
        callback(/^[A-Za-z0-9]{1,5}[-\s]?[A-Za-z0-9]{3,9}$/.test(zip));
    }
}

并使用 Promises,在本例中 jQuery.Deferred-objects

此代码需要 jQuery 1.8 或更高版本,因为低于该版本的 then 方法的行为似乎有所不同(奇怪/意外/错误)

https://jsfiddle.net/jge4439p/

//returns a promise
function validateZip(countryCode, zip) {
    if (countryCode == 'US' && /^\d{5}([-\s]?\d{4})?$/.test(zip)) {
        // US validation
        return getZipJson(zip).then(function(response){
            return isValid( response.results[0].address_components );
        });
    } else {
        // international validation
        return $.when(/^[A-Za-z0-9]{1,5}[-\s]?[A-Za-z0-9]{3,9}$/.test(zip));
    }
}

//also returns a promise ;)
function getZipJson(zip) {
    // need to add google api key to data
    return $.ajax({
        type: 'GET',
        url: '//maps.googleapis.com/maps/api/geocode/json',
        dataType: 'json',
        data: { address: zip }
    });
}

//an ES5-version of isValid()
function isValid(address_components) {
    var isCountry = function(type){ return type === 'country' };
    return address_components.some(function(component){
        return (component.long_name === 'United States' || component.long_name === 'USA')
            && component.types.some(isCountry);
    });
}

以及用法:

var isValidPromise = validateZip("US", "12345");

isValidPromise.then(function(v){
    console.log("isValid", v);
});

左右:

validateZip("US", "12345").then(function(isValid){
    if(isValid){
        console.log("hooray");
    }else{
        console.log("ney");
    }
});

再一看,函数getZipJsonisValid是如此具体,我不知道我是否会超越代码。这里是组合代码,再次作为 promise :

function validateZip(countryCode, zip) {
    if (countryCode == 'US' && /^\d{5}([-\s]?\d{4})?$/.test(zip)) {
        // US validation
        var names = ['United States', 'USA'];           
        //using lambdas, because it's more compact and contains all necessary info
        var isValidComponent = comp => Boolean(comp && ~names.indexOf( comp.long_name ) && ~comp.types.indexOf( 'country' ));
        var isValid = result => isValidComponent( result.address_components );

        return $.ajax({
            type: 'GET',
            url: '//maps.googleapis.com/maps/api/geocode/json',
            dataType: 'json',
            data: { address: zip }
        }).then( response => response.results.some( isValid ) );
    } else {
        // international validation
        return $.when(/^[A-Za-z0-9]{1,5}[-\s]?[A-Za-z0-9]{3,9}$/.test(zip));
    }
}

关于Javascript AJAX 函数返回类型未定义,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37334673/

相关文章:

javascript - js 更改变量会影响原始变量

javascript - jQuery - 如何在附加的选择器上链接事件

javascript - Fetch Api 无法从 PHP 服务器获取 Session

jquery - 如何获取 jquery 自动完成值进行搜索?

javascript - 正文标签类 ReGex

javascript - 如何获取属于 html 中某个类的所有 div,除非它们是特定的 div,否则更改它们的类?

jquery - 货币正则表达式

javascript - 如何从异步调用返回响应?

jquery ajax加载gif

javascript - 回溯历史后 Firefox 中的 Ajax 调用缓存