我在使用jQuery将ajax调用嵌套到Wikipedia api时遇到问题。 HTML很简单,只是一个输入表单和一个按钮:
$data2
该搜索按钮具有一个事件侦听器,该事件侦听器会触发从维基百科API抓取数据的函数:
<input id='search-input' type="text" class="form-control">
<button id="search-button" type="button" class="btn btn-primary">Search</button>
<div id ='outputDiv'></div>
但是,...
searchBtn.addEventListener('click', searchwiki);
...
function searchwiki(){
let searchTermObjects =[]
let term = inputfield.value;
let titleUrl = search_term(term);
createWikiObject(titleUrl).then(function(){
searchTermObjects.forEach(function(elem){
addExtrctToObj(elem)
})
}).then(function(data){
append_result(searchTermObjects)
})
}
function createWikiObject(titleUrl){
return $.ajax({
type: "GET",
url: titleUrl,
dataType : 'jsonp',
async: true,
error : function(ermsg){
console.log('error in searching',ermsg)
},}).then(function(data){
for(let i = 0; i < data[1].length; i ++){
searchTermObjects.push({
'title': data[1][i].replace(/\s+/g, '_'),
'description': data[2][i],
'url': data[3][i],
})
}; // this for loop should push each result as an object to an array named searchtTermObjects, and i am planning to use this array in the next ajax call to add another property named extract to each object in array
}
);
}
function addExtrctToObj(obj){
console.log(obj)
return $.ajax({
type: "GET",
url: get_text(obj['title']),
dataType : 'jsonp',
async: true,
error : function(ermsg){
console.log('error getting text',ermsg)
}
}).then(function (data){
let pageID = Object.keys(data.query.pages);
if(data.query.pages[pageID].hasOwnProperty('extract')){
obj['extract'] = data.query.pages[pageID].extract;
}
// this function adds the extracted text for each article ,
// the searchTermObjects now looks something like:
/ [{'title':...,'url':...,'description':...,'extract':..},{...}]
})
};
function append_result(termsObjectsArray){
// this function should loop through the searchtermobjects and append leading text for each object in the array to the Output div under the button
for (let i = 0; i < termsObjectsArray.length; i++){
let newDiv = document.createElement('div');
目前仅返回三个键,而没有看到提取键'
Object.keys(termsObjectsArray[i])
这里是我出错的地方-newDiv的inerHtml值未定义
console.log(Object.keys(termsObjectsArray[i]))
newDiv.classList.add('wiki-result');
newDiv.innerHTML = termsObjectsArray[i]["extract"];
在我 outputDiv.appendChild(newDiv);
}
}
// the api calls are formed with these functions:
let base_url = "https://en.wikipedia.org/w/api.php";
function search_term(term) {
let request_url = base_url + "?action=opensearch&search=" + term + "&format=json&callback=?";
return request_url;
}
function get_text(term){
let request_url = base_url + "?action=query&prop=extracts&exintro=&format=json&titles=" + term; // explaintex= returns plaintext, if ommited returns html
return request_url;
}
之后,我得到了我所需要的,带有对象的数组,这些对象具有正确名称的所有4个属性,但是我不明白为什么console.log(searchTermObjects)
函数看不到'提取物键。
在控制台中记录的对象旁边是“ i”符号,上面写着“下面的值现在才被求值”,在那里,我有了我想要的-每个搜索结果都是带有标题,URL,描述,并提取密钥。
将此代码复制到您的IDE中,以查看是否可以帮助我找到解决方案。
答案 0 :(得分:0)
我相信您遇到的问题是,您正在尝试返回Deferred对象,并且由于推迟而没有任何返回。
return $.ajax({
type: "GET",
url: get_text(obj['title']),
dataType : 'jsonp',
async: true,
error : function(ermsg){
console.log('error getting text',ermsg)
}
})
async
的值为true,因此代码在请求完成之前继续运行,并且您将获得空值。
尝试设置async: false
,看看是否有更好的响应。正如安德鲁·洛尔(Andrew Lohr)在评论中指出的那样,这不是解决问题的好方法,它只会告诉您是否是问题所在。
如果是,那么我建议不要将请求分解为多个功能。您应该只使用延迟方法将AJAX调用链接起来。它的结构如下:
$.ajax({ ... }).then(function(data){
// ... do something with the data ...
// Make your followup request.
$.ajax({ ... }).then(function(data) {
// ... finalize the response ...
});
});
还可以考虑在ajax调用中使用context
选项来传递回调方法,该方法一旦链完成就可以触发。