You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何解决AJAX异步调用延迟导致函数返回null的问题?

问题原因
  • AJAX异步执行特性:$.ajax默认是异步请求,发送请求后不会阻塞后续代码执行,getLocationData函数会在AJAX请求还没拿到响应的时候就直接执行结束。你在done回调里写的return语句,返回的是done这个回调函数的返回值,根本不是getLocationData的返回值,getLocationData本身没有显式写返回,默认返回undefined,所以你赋值的locationData自然是空的。
  • 执行顺序逻辑:JS执行异步任务时会把回调放到事件队列,先执行完主线程的所有同步代码,才会去执行事件队列里的异步回调。所以你点击事件里的console.log是同步代码,会先执行,等主线程空闲、AJAX请求拿到响应后,才会执行done里的console.log,就出现了你看到的顺序颠倒的情况。
  • 拼写错误:你定义的函数名是getLocationData,但是点击事件里调用的时候写的是getLocationsData,多了一个s,也会导致调用报错拿不到返回值。
解决方法

推荐用Promise + async/await的方案改造代码,逻辑更清晰:

  1. 改造getLocationData函数,让它返回Promise实例
const baseUrl = 'https://booking-com.p.rapidapi.com/v1/hotels/';
var locale = "en-gb";

function getLocationData(){
    return new Promise((resolve, reject) => {
        var destination = {};
        var location = $('#location').val();
        var route = "";
        // 原逻辑||改为&&,避免空字符串也生成请求路径
        if(location != null && location != ""){
            // 对用户输入做URL编码,避免特殊字符导致请求报错
            route = `locations?locale=${locale}&name=${encodeURIComponent(location)}`;
        }
        console.log(`${baseUrl}${route}`);
        $.ajax({
            method: "GET",
            url: `${baseUrl}${route}`,
            headers:{
                'x-rapidapi-host': 'booking-com.p.rapidapi.com',
                'x-rapidapi-key': 'api-key'
            }
        })
        .done(response => {
            if(response[0]["dest_type"] != "hotel"){
                destination = {
                    "label":response[0]["label"],
                    "dest_id": response[0]["dest_id"],
                    "dest_type": response[0]["dest_type"]
                };
            }
            console.log("getLocationData()", destination);
            resolve(destination);
        })
        .fail(response => {
            console.log("ajax failed",response);
            reject(response);
        });
    })
}
  1. 改造点击事件,用async/await等待异步请求结果
// 回调函数前加async关键字,支持内部使用await
$('#search-hotels').click(async function () {
    let dateRange = getDateRangeObject();
    let checkin = dateRange['checkin'];
    let checkout = dateRange['checkout'];
    let isCheckinInvalid = moment(checkin).isBefore(moment(new Date()).format('YYYY-MM-DD'));
    let isCheckoutInvalid = moment(checkout).isBefore(moment(new Date()).add(1, 'days').format('YYYY-MM-DD'));

    let adults = $('#adults').val();
    let rooms = $('#rooms').val();
    let isAdultsAndRoomValid = adults >= 1 && rooms >= 1;
    // 加await等待请求返回,同时修正函数名拼写错误
    let locationData = await getLocationData();
    
    let destination = {...locationData};
    console.log("click button function",destination);

    // 原逻辑缺少location变量定义,补充获取输入框值
    let location = $('#location').val();
    if (location != "" && !isCheckinInvalid && !isCheckoutInvalid && isAdultsAndRoomValid) {
        window.location.href = `hotels.html?location=${encodeURIComponent(location)}&checkin=${checkin}&checkout=${checkout}&adults=${adults}&rooms=${rooms}`;
    }

    return false;
});

内容的提问来源于stack exchange,提问作者Enchantres

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.24 17:36:04