jQuery - 嵌套ajax调用并使用每次调用的数据 ?

内容来源于 Stack Overflow,并遵循CC BY-SA 3.0许可协议进行翻译与使用

  • 回答 (1)
  • 关注 (0)
  • 查看 (187)

我在使用jQuery将ajax调用嵌套到wikipedia api时遇到了问题。HTML很简单,只是一个输入表单和一个按钮:

<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>

搜索按钮有一个事件监听器,它触发一个从维基百科API中获取数据的函数:

...
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])只返回三个键,并且看不到提取键'

        console.log(Object.keys(termsObjectsArray[i]))
        newDiv.classList.add('wiki-result');
        newDiv.innerHTML = termsObjectsArray[i]["extract"];

这是我得到错误的地方 - newDiv的inerHtml有价值UNDEFINED

        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;
    }

afetr我console.log(searchTermObjects)得到我需要的东西,数组中的对象具有正确名称的所有4个属性,但我不明白为什么append_result函数看不到'extract'键。

提问于
用户回答回答于

我相信你遇到的问题是你试图返回一个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 ...
    });
});

扫码关注云+社区

领取腾讯云代金券