我必须有一些简单的东西,但是唉,我不知道我不知道的是什么。下面是我试图从USGS获得当前流量条件的代码。
// create site object
function Site(siteCode) {
this.timeSeriesList = [];
this.siteCode = siteCode;
this.downloadData = downloadData;
this.getCfs = getCfs;
// create reference to the local object for use inside the jquery ajax function below
var self = this;
// create timeSeries object
function TimeSeries(siteCode, variableCode) {
this.variableCode = variableCode;
this.observations = [];
}
// create observation object
function TimeSeriesObservation(stage, timeDate) {
this.stage = stage;
this.timeDate = timeDate;
}
// include the capability to download data automatically
function downloadData() {
// construct the url to get data
// TODO: include the capability to change the date range, currently one week (P1W)
var url = "http://waterservices.usgs.gov/nwis/iv/?format=json&sites=" + this.siteCode + "&period=P1W¶meterCd=00060,00065"
// use jquery getJSON to download the data
$.getJSON(url, function (data) {
// timeSeries is a two item list, one for cfs and the other for feet
// iterate these and create an object for each
$(data.value.timeSeries).each(function () {
// create a timeSeries object
var thisTimeSeries = new TimeSeries(
self.siteCode,
// get the variable code, 65 for ft and 60 for cfs
this.variable.variableCode[0].value
);
// for every observation of the type at this site
$(this.values[0].value).each(function () {
// add the observation to the list
thisTimeSeries.observations.push(new TimeSeriesObservation(
// observation stage or level
this.value,
// observation time
this.dateTime
));
});
// add the timeSeries instance to the object list
self.timeSeriesList.push(thisTimeSeries);
});
});
}
// return serialized array of cfs stage values
function getCfs() {
// iterate timeseries objects
$(self.timeSeriesList).each(function () {
// if the variable code is 00060 - cfs
if (this.variableCode === '00060') {
// return serialized array of stages
return JSON.stringify(this.observations);
}
});
}
}
当我直接使用命令行访问对象时,我可以使用以下方法访问单个观察:
> var watauga = new Site('03479000')
> watauga.downloadData()
> watauga.timeSeriesList[0].observations[0]
我甚至可以使用以下方法访问带有时间戳的所有报告值:
> JSON.stringify(watauga.timeSeriesList[0].observations)
现在我试图将这个逻辑包装到getCfs函数中,但收效甚微。我错过了什么?
答案 0 :(得分:0)
我在上面的代码中没有看到任何强制下载数据的内容。也许在你用来调用getCfs()
的任何执行路径中,你有一个等待或循环来检查下载是否在调用getCfs()
之前完成,但是如果你只是在调用
site.downloadData();
site.getCfs()
当你致电site.getCfs()
时,你几乎肯定没有完成加载。
您需要从success
处理程序中调用回调来通知调用者数据已下载。例如,将Site.downloadData
的签名更改为
function downloadData(downloadCallback) {
// ...
完成数据处理后,添加对downloadCallback
的调用:
// After the `each` that populates 'thisTimeSeries', but before you exit
// the 'success' handler
if (typeof downloadCallback === 'function') {
downloadCallback();
}
然后你的调用将是:
var watauga = new Site('03479000');
var downloadCallback = function() {
watauga.timeSeriesList[0].observations[0];
};
watauga.downloadData(downloadCallback);
这样,您可以确保在尝试访问数据之前完成数据处理。
如果您在代码的其他部分获得了undefined
,那么可能还有其他错误。在其上抛出一个调试器并逐步执行。请记住,交互式调试与交互式调用脚本有许多相同的问题;在开始检查变量之前,脚本有时间在后台完成下载,这使得它看起来像一切都很糟糕,实际上非交互式执行会有不同的时间。
答案 1 :(得分:0)
真正的问题,我通过刚从头开始发现这个函数,我的jQuery.().each()
的实现出了问题。我第二次尝试使用标准的for in
循环。这是工作代码。
function getCfs() {
for (var index in this.timeSeriesList) {
if (this.timeSeriesList[index].variableCode === '00060'){
return JSON.stringify(this.timeSeriesList[index].observations);
}
}
}
另外,你正在谈论@Palpatim的一些内容,我肯定要研究。感谢您指出这些注意事项。这似乎是进一步研究这些承诺的好时机。