【问题标题】:Save the result of a JSONP callback to an outer object将 JSONP 回调的结果保存到外部对象
【发布时间】:2016-12-30 12:32:10
【问题描述】:

经过几天打破我的想法并尝试自己解决我的问题后,我决定寻求一些帮助。这是我的代码:

// -----------
// Global object
// -----------
window.myObj = window.myObj || {};
function getLocation(myObj) {
    // Location test
    // -- Mobile connection test/fix
    // -- First step => Ask on client IP
    $.getJSON( "//freegeoip.net/json/?callback=?", function(data) {
        console.warn('Fetching Accurate JSON data...');
        if (data.city !== '') {
            // Log output to console
            console.info('Location found from client ip');
            console.info(JSON.stringify(data, null, 2));
            // myObj = data;
            // myObj.toString = function(data) {
            //  return JSON.stringify(data, null, 2);
            // }
        } else {
            // -- Second step => Ask on server IP using server name
            $.getJSON( "//freegeoip.net/json/" + window.location.host + "?callback=?", function(data) {
                // Log output to console
                console.info('Location found from server ip');
                console.info(JSON.stringify(data, null, 2));
                // myObj = data;
                // myObj.toString = function(data) {
                //  return JSON.stringify(data, null, 2);
                // }
            });
        }
    });

    return myObj;
}
console.info(getLocation(myObj));

我想要的是将 JSONP 回调的结果存储到名为 myObj 的外部对象中。

我尝试以这种方式将函数创建为闭包:

window.myObj = (function () {
    // Location test
    // -- Mobile connection test/fix
    // -- First step => Ask on client IP
    $.getJSON( "//freegeoip.net/json/?callback=?", function(data) {
        console.warn('Fetching Accurate JSON data...');
        if (data.city !== '') {
            // Log output to console
            console.info('Location found from client ip');
            return data;
        } else {
            // -- Second step => Ask on server IP using server name
            $.getJSON( "//freegeoip.net/json/" + window.location.host + "?callback=?", function(data) {
                // Log output to console
                console.info('Location found from server ip');
                return data;
            });
        }
    });
}());

但它每次都返回undefined...您可能会看到我的javascript技能不太好,就像我的英语一样。

提前感谢大家的帮助。

【问题讨论】:

    标签: javascript jquery reactjs jsonp


    【解决方案1】:

    所以...经过大量关于 Javascript 语言的研究,我自己找到了解决方案。以下是我解决问题的方法:

    // -----------
    // Global JS Object
    // -----------
    var myObj = myObj || {};
    
    // Dependency
    // Object size count function. Thanks to:
    // http://stackoverflow.com/a/24457767
    myObj.objSize = function(obj) {
        var count = 0;
        var key;
    
        if (typeof obj == "object") {
            if (Object.keys) {
                count = Object.keys(obj).length;
            } else if (window._) {
                count = _.keys(obj).length;
            } else if (window.$) {
                count = $.map(obj, function() { return 1; }).length;
            } else {
                for (key in obj) if (obj.hasOwnProperty(key)) count++;
            }
        }
    
        return count;
    }
    
    // Setter method
    myObj.setUserDetails = function(data) {
        this.user = {};
        this.user.details = data;
        this.user.location = {lat: data.latitude, lng: data.longitude};
        this.user.location.toString = function() {
            // Returns data as same format as Google use...
            return '(' + this.user.location.lat + ', ' + this.user.location.lng + ')';
        }.bind(this);
    }
    
    // Getter method
    myObj.getUserDetails = function() {
        var _this = this;
    
        // -- Mobile connection test/fix
        var valid_region_codes = ['GE', 'BE', 'FR', 'VD', 'VS', 'NE', 'JU'];
    
        // Checking if you we've not already some user data
        if (typeof _this.user !== 'object') {
            // -- First step => Ask on client IP
            $.getJSON( "//freegeoip.net/json/?callback=?", function(first_fetch) {
                console.warn('Fetching Accurate JSON data...');
                if (first_fetch.region_code === '') {
                    // -- Empty 'region_code' => Ask on server IP using server name
                    $.getJSON( "//freegeoip.net/json/" + window.location.host + "?callback=?", function(second_fetch) {
                        // Log output to console
                        console.info('Fetch: 2');
                        console.info('Location based on server ip');
                        console.info(JSON.stringify(second_fetch, null, 2));
                        console.info(this); console.info(_this);
                        _this.setUserDetails(second_fetch);
                    });
                } else {
                    // -- Have 'region_code', let's proceed...
                    if (valid_region_codes.indexOf(first_fetch.region_code) !== -1) {
                        // Checked 'region_code'... Valid, using client IP
                        console.info('Fetch: 1');
                        console.info('Location based on client ip');
                        console.info(JSON.stringify(first_fetch, null, 2));
                        console.info(this); console.info(_this);
                        _this.setUserDetails(first_fetch);
                    } else {
                        // Checked 'region_code'... not valid, falling back to server IP
                        $.getJSON( "//freegeoip.net/json/" + window.location.host + "?callback=?", function(third_fetch) {
                            // Log output to console
                            console.info('Fetch: 3');
                            console.info('Location based on server ip');
                            console.info(JSON.stringify(third_fetch, null, 2));
                            console.info(this); console.info(_this);
                            _this.setUserDetails(third_fetch);
                        });
                    }
                }
            });
        } else {
            console.warn('Using previously fetched user data...');
        }
    }
    
    // The Holy Grail method (^_^)
    myObj.waitForProps = function(prop, type, timer, callback) {
        var check = setInterval(function() {
            var evil = eval(prop), evilSize = masalle.objSize(evil);
            console.info('Checking [prop] as: ' + prop + '\nTo type: ' + type +
                         '\nEach: ' + timer + 'ms\nThen exec callback:\n\t\t\t' + callback);
            if (typeof evil === type) {
                console.info('[' + prop + '] found, checking size...');
                if (evilSize > 0) {
                    console.info('[' + prop + '] size: ' + evilSize);
                    clearInterval(check);
                    if (callback && typeof callback === 'function') {
                        callback();
                    }
                }
            }
        }, timer);
    }
    

    说明

    首先,我调用getter 方法myObj.getUserDetails(),它使用setter 方法myObj.setUserDetails() 将JSONP 请求的内容插入到名为myObj.user 的对象中

    然后,我调用我的魔法方法(类似于waiting 方法)来检查对象myObj.user 是否存在

    如果它已经可用,我正在使用它并执行指定的callback 或者我正在根据指定的持续时间迭代wait 计时器,直到请求的对象可用,然后它执行callback

    用法

    // Grab the user location
    myObj.getUserDetails();
    
    // Wait the time the required object to be created / filed
    myObj.waitForProps('myObj.user', 'object', 600, function() {
        // Execute what you need there
    });
    

    我希望这对某人有用。如果您知道更好(更快)的方法来做同样的事情,请随时与我联系。

    已知问题:

    我知道我在我的魔法方法中使用了邪恶的 eval 函数 可能会导致一些安全问题。我希望我正确使用它,如果 不,请更正我的代码。

    如果您在 a 中使用方法 myObj.waitForProps() ReactJS 项目,你会看到没有遵守指定的持续时间 并且该方法尽可能快地迭代,直到您请求的对象 可用。如果您对此问题有任何提示,请告诉我,也许是我的 代码只是工作错误......

    【讨论】:

      猜你喜欢
      • 2019-01-03
      • 2010-11-23
      • 2017-06-29
      • 1970-01-01
      • 2015-05-29
      • 2013-09-20
      • 2017-10-07
      • 2011-10-31
      • 1970-01-01
      相关资源
      最近更新 更多