我是一名学生,正在为我大学的图书馆网站开发一个电影浏览器项目。我有一些 Javascript 经验,但除了对这个项目的研究之外,我没有使用 XML 或 JSON 的经验。
我必须使用隐藏的 API 密钥查询我们馆藏中所有 DVD 的 WorldCat 搜索 API,并将 MARCXML 结果转换为 JSON。库服务器不支持服务器端脚本,所以我选择使用 Yahoo Pipes,它允许我将 API 密钥“隐藏”在私有字符串中,并将结果作为 JSON 返回。
我的问题是有时(但肯定不总是)我会收到一条错误消息:
TypeError: root is undefined
我假设与此错误的不一致是由于加载时间造成的(也许 Javascript 试图在 JSON 对象完全加载之前执行?如何提高代码效率以避免此错误?感谢您的任何建议。
下面你会发现我的代码的一个简短示例,它有时会重新创建此错误:
<!DOCTYPE html>
<html>
<head>
<script>
var my_JSON_object = {};
var movieArray = new Array();
var subject = 'Science+Fiction';
var recordSet = 1;
loadJSON(0);
function loadJSON(set)
{
if (set == 0)
var yahooPipe = 'http://pipes.yahoo.com/pipes/pipe.run?_id=b54472aff1548e93022d07fddfd6aa38&_render=json&maximumRecords=20&startRecord=1&subject='+subject+'&_callback=getData';
else
var yahooPipe = 'http://pipes.yahoo.com/pipes/pipe.run?_id=b54472aff1548e93022d07fddfd6aa38&_render=json&maximumRecords=20&startRecord='+((set*20)+1)+'&subject='+subject+'&_callback=getNextData';
var head = document.getElementsByTagName('head')[0];
var newJS = document.createElement('script');
newJS.type = 'text/javascript';
newJS.src = yahooPipe;
head.appendChild(newJS);
}
function getData(json)
{
my_JSON_object = json;
if (my_JSON_object.value.items[0].numberOfRecords>0)
prepData(0);
else
alert("No results...");
}
function getNextData(json)
{
my_JSON_object = json;
prepData(recordSet);
}
function loadData()
{
loadJSON(recordSet);
recordSet++;
}
function prepData(set)
{
var root = my_JSON_object.value.items[0];
if (set == 0 && root.numberOfRecords == 1)
{
root.records.record[0] = root.records.record;
}
for (var i=0; i<20; i++)
{
if (root.records.record[i]==undefined)
{
document.getElementById('A1').innerHTML=root.numberOfRecords;
document.getElementById('A2').innerHTML=movieArray[set*20+i-1];
break;
}
for (var j=0; j<root.records.record[i].recordData.record.datafield.length; j++)
{
if (root.records.record[i].recordData.record.datafield[j].tag == 245)
{
for (var k=0; k<root.records.record[i].recordData.record.datafield[j].subfield.length; k++)
{
if (root.records.record[i].recordData.record.datafield[j].subfield[k].code == "a")
{
movieArray[i+(set*20)] = root.records.record[i].recordData.record.datafield[j].subfield[k].content;
break;
}
}
}
}
}
if (set*20<root.numberOfRecords)
loadData();
}
</script>
</head>
<body>
<p><b>Results:</b><span id="A1"></span></p>
<p><b>Title(last record):</b><span id="A2"></span></p>
</body>
</html>