我有一个函数,它接受一个参数并进行同步加载。
我将其更改为执行异步 jQuery.ajax 调用以检索数据并调用回调。旧代码(无法修改)使用相同的功能并失败。我需要能够以两种方式检索数据,以便异步代码可以继续运行,如果异步已经加载,旧同步代码可以检索缓存的数据,同步加载或等待任何已经运行的异步请求。
var ajaxQueries = {}
loadEngineData(fileId, callback) {
var sync = callback == undefined;
if (ajaxQueries[fileId]) {
if (sync) {
//Need to stop here and wait for ajaxQueries[fileId] to finish
//Execution cannot continue! If we return before defered has ended here 3rd party scripts will fail.
return data;
}
else {
ajaxQueries[fileId].done(function(data){callback(data)});
}
}
else {
ajaxQueries[fileId] = $.ajax({
async:!sync,
type:'GET',
url:fileId2Name(fileId),
data:null,
dataType:'text',
});
if (sync) {
var _data = undefined;
ajaxQueries[fileId].done(function(data){_data=data});
return _data;
}
ajaxQueries[fileId].done(function(data){callback(data);});
}
}
如果旧脚本调用该函数,则 ajax 查询将同步运行,所有后续调用都将使用延迟.done
,.fail
一切都会好起来的。
var enginePhyData = loadEngineData('physics');
//Do stuff
如果一个新脚本首先调用该函数,并且在此加载过程中,一个旧脚本尝试从同一文件加载数据,我会遇到延迟 ajax 查询ajaxQueries[fileId]
异步运行的情况,我必须等待它完成加载数据以避免破坏现有的库。
我简化loadEngineData
以保持问题的集中。否则它会更复杂一些,并允许调用文件列表以并行加载
loadEngineData(['geometry', 'scripts'], function() {
var phy = loadEngineData('physics');
var geo = loadEngineData('geometry');
var scr = loadEngineData('scripts');
//run the async function;
});
loadEngineData('physics', function() {
//run the async function;
});
//...
//in the scripts file
var phy = loadEngineData('physics');
//here phy might be undefined if this file went through eval() before `loadEngineData('physics',...)` was called;
我可以对代码进行现代化改造,但问题是某些文件在项目之间共享并在不同的环境中运行。如果不分叉依赖项,我目前无法修改旧脚本。