Jquery 如何停止javascript以等待延迟完成?
我有一个函数,它接受一个参数并执行同步加载 我将其更改为执行异步jQuery.ajax调用以检索数据并调用回调。旧代码(无法修改)使用相同的函数,但失败。我需要能够以两种方式检索数据,以便异步代码可以继续运行,并且旧的同步代码可以检索缓存数据(如果异步已加载)、同步加载或等待任何已运行的异步请求Jquery 如何停止javascript以等待延迟完成?,jquery,Jquery,我有一个函数,它接受一个参数并执行同步加载 我将其更改为执行异步jQuery.ajax调用以检索数据并调用回调。旧代码(无法修改)使用相同的函数,但失败。我需要能够以两种方式检索数据,以便异步代码可以继续运行,并且旧的同步代码可以检索缓存数据(如果异步已加载)、同步加载或等待任何已运行的异步请求 var ajaxQueries = {} loadEngineData(fileId, callback) { var sync = callback == undefined; if
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
如果一个新脚本首先调用函数,并且在加载过程中,一个旧脚本试图从同一个文件加载数据,那么最后的情况是,ajaxquerys[fileId]
中的延迟ajax查询正在异步运行,我必须等待它完成加载数据,以避免破坏现有的libs
我简化了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;
我可以使代码现代化,但问题是一些文件在项目之间共享,并在不同的环境中运行。我目前无法在不分叉依赖项的情况下修改旧脚本。在等待某个异步ajax调用完成时,无法停止javascript的执行。Javascript根本不是这样工作的
相反,您必须重新设计编程方式,以便希望等待异步ajax调用完成的代码将通过回调函数执行,而不是在ajax调用执行后同步执行。如果是同步请求,您只需要返回responseText
return data
变成
return ajaxQueries[fileId].responseText;
因为请求是同步的,所以不需要等待,浏览器已经在等待响应了
var ajaxQueries = {}
loadEngineData(fileId, callback) {
var sync = callback == undefined;
if (ajaxQueries[fileId]) {
if (sync) {
return ajaxQueries[fileId].responseText;
}
else {
...
您试图使异步代码同步,但这不会起作用。如果没有可能的分页副作用,您不能在x条件出现之前停止代码执行。您的选项是:不要使用旧方法,创建一个新方法,以便旧方法继续同步工作,或者修改旧代码的工作方式,使其异步工作。@KevinB:据我所知,调用
$.ajax({async:false,…});
停止代码执行。或者我错了吗?是的,错了。但是在您的情况下,您可以这样做吗?看起来您当前拥有的几乎可以正常工作(添加了return$.parseJSON(ajaxquerys[fileId].responseText)
假设请求总是进入if语句的后半部分,这就带来了一个问题:您实际需要什么?如果旧脚本首先调用函数来检索所需数据,我们将得到$.ajax({async:false,…})
否则不行。您说在后一种情况下,在恢复之前无法等待延迟结束?我将编辑问题以使其正确。我缺少的是在脚本调用函数期望返回响应时等待异步请求完成的代码。ajaxquerys[fileId]中的ajax查询
可能还没有结束,因为它可能是异步启动的,在这种情况下,我返回未定义的
,脚本失败。如果sync为false,它将永远不会进入该部分,并将其发送到else,在那里它正确处理异步请求,这意味着如果它的同步数据将在第一次和第二次都从该方法返回以及后续时间,如果是异步的,则在请求时将调用提供的回调。现在,如果您发出同步请求,然后将其用作异步(反之亦然),则可能会遇到问题。