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

固定jsonpCallback的多JSONP请求上下文被覆盖问题求解

确实,你推测的问题点完全正确:当指定固定的jsonpCallback时,jQuery会把这个函数注册为全局变量,每次发起新请求都会覆盖这个全局函数的定义。所以多个异步JSONP请求返回时,只有最后一次注册的回调逻辑会生效(或者因为请求返回顺序随机,导致部分回调丢失),自然没法保证所有contextvar都被打印出来。

下面给你两种可行的解决办法:

方法1:用全局队列存回调

自己维护一个全局队列来保存每个请求的回调,同时自定义固定的myFunc函数,让它每次从队列里取出回调执行:

// 全局队列,用来存每个请求的回调函数
const jsonpCallbackQueue = [];

// 自己定义全局的myFunc,不让jQuery自动生成覆盖它
window.myFunc = function(data) {
    if (jsonpCallbackQueue.length > 0) {
        const callback = jsonpCallbackQueue.shift();
        callback(data);
    }
};

var requestMaker = function(url, contextvar) {
    // 绑定当前请求的contextvar到回调里
    const handleDone = function(data) {
        console.log(contextvar);
    };

    $.ajax({
        url: url,
        crossDomain: true,
        dataType: 'jsonp',
        jsonp: 'callback', // 对应接口接受的回调参数名,这里适配w3schools的接口
        jsonpCallback: "myFunc",
        beforeSend: function() {
            // 发送请求前,把当前回调加入队列
            jsonpCallbackQueue.push(handleDone);
        }
    });
};

// 发起请求
requestMaker("https://www.w3schools.com/js/demo_jsonp.php", "request1");
requestMaker("https://www.w3schools.com/js/demo_jsonp.php", "request2");
requestMaker("https://www.w3schools.com/js/demo_jsonp.php", "request3");
requestMaker("https://www.w3schools.com/js/demo_jsonp.php", "request4");

注:如果请求返回顺序和发送顺序不一致,打印的contextvar顺序会和发送顺序不同,但所有值都会被打印出来。

方法2:闭包链式保存回调(更靠谱)

利用闭包每次保存当前的全局myFunc,重新定义新的myFunc时链式调用之前的回调,不管请求返回顺序如何,所有回调都会被执行:

var requestMaker = function(url, contextvar) {
    // 先把当前全局的myFunc存起来
    const originalMyFunc = window.myFunc;

    // 重新定义全局myFunc:先执行当前请求的回调,再调用之前存的myFunc
    window.myFunc = function(data) {
        console.log(contextvar);
        // 如果之前有myFunc,继续执行它的逻辑
        if (originalMyFunc) {
            originalMyFunc(data);
        }
    };

    $.ajax({
        url: url,
        crossDomain: true,
        dataType: 'jsonp',
        jsonp: 'callback',
        jsonpCallback: "myFunc"
    });
};

// 发起请求
requestMaker("https://www.w3schools.com/js/demo_jsonp.php", "request1");
requestMaker("https://www.w3schools.com/js/demo_jsonp.php", "request2");
requestMaker("https://www.w3schools.com/js/demo_jsonp.php", "request3");
requestMaker("https://www.w3schools.com/js/demo_jsonp.php", "request4");

这种方式下,每个请求的myFunc都会“继承”之前的版本,不管哪个请求先返回,所有绑定的contextvar都会被打印,只是顺序可能随请求返回顺序变化,但不会漏掉任何值。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.01 23:20:39