我有一個函數,它需要一個參數並進行同步加載。JavaScript如何停止等待延遲完成?
我改變它做異步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
如果一個新的腳本調用函數首先,這加載一箇舊腳本試圖從同一個文件中加載數據時,我結束與其中ajaxQueries[fileId]
遞延AJAX查詢異步運行的情況下,我必須等待它完成加載數據以避免打破現有的庫。
我簡化了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;
我可以現代化的代碼加載,但問題是,有些文件是跨項目共享,並在不同的環境中運行。我目前無法修改舊腳本而不分散依賴關係。
您試圖使異步代碼同步,這將無法正常工作。你不能停止代碼執行,直到x條件,沒有可能的破壞性的副作用。 –
您的選擇是:單獨保留舊方法並製作新方法,以便舊方法可以繼續同步工作,或者修改舊代碼的工作方式以使其異步工作。 –
@KevinB:據我所知調用'$ .ajax({async:false,...});'停止代碼執行。或者我錯了? – Coyote