固定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
相关产品推荐
相关产品推荐

