将 JSONP 回调的结果保存到外部对象
Save the result of a JSONP callback to an outer object
经过几天让我心碎并尝试自己解决我的问题后,我决定寻求帮助。这是我的代码:
// -----------
// 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;
});
}
});
}());
但它 returns undefined
每次...你可能会看到我的 javascript 技能不是很好,因为我的英语也是。
在此先感谢大家的帮助。
所以...在对 Javascript 语言进行大量研究后,我自己找到了解决方案。以下是我如何处理我的问题:
// -----------
// Global JS Object
// -----------
var myObj = myObj || {};
// Dependency
// Object size count function. Thanks to:
//
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
});
我希望这对某些人有用。如果您知道更好(更快)的方法来做同样的事情,请随时与我联系。
Known issues:
I know I've used the evil eval
function in my magic method which
could led to some security issues. I hope I've used it correctly, if
not, please correct my code.
If you're using the method myObj.waitForProps()
in a
ReactJS project, you'll see that the specified duration is not respected
and the method iterates as fast as possible till your requested object
is available. Let me know if you have a tips to this issue, maybe my
code is just working wrong...
经过几天让我心碎并尝试自己解决我的问题后,我决定寻求帮助。这是我的代码:
// -----------
// 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;
});
}
});
}());
但它 returns undefined
每次...你可能会看到我的 javascript 技能不是很好,因为我的英语也是。
在此先感谢大家的帮助。
所以...在对 Javascript 语言进行大量研究后,我自己找到了解决方案。以下是我如何处理我的问题:
// -----------
// Global JS Object
// -----------
var myObj = myObj || {};
// Dependency
// Object size count function. Thanks to:
//
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
});
我希望这对某些人有用。如果您知道更好(更快)的方法来做同样的事情,请随时与我联系。
Known issues:
I know I've used the evil
eval
function in my magic method which could led to some security issues. I hope I've used it correctly, if not, please correct my code.If you're using the method
myObj.waitForProps()
in a ReactJS project, you'll see that the specified duration is not respected and the method iterates as fast as possible till your requested object is available. Let me know if you have a tips to this issue, maybe my code is just working wrong...