Javascript-暂停执行,直到标志变为true
如何暂停javascript执行,直到标志变为真 例如,我有这样一条xml消息:Javascript-暂停执行,直到标志变为true,javascript,jquery,synchronization,sync,wait,Javascript,Jquery,Synchronization,Sync,Wait,如何暂停javascript执行,直到标志变为真 例如,我有这样一条xml消息: [...] <action> <resource update>id</resourceupdate> </action> <action> <event>id1</event> </action> <action> <event>id2</event> <
[...]
<action>
<resource update>id</resourceupdate>
</action>
<action>
<event>id1</event>
</action>
<action>
<event>id2</event>
</action>
<action>
<event>id3</event>
</action>
[...]
function browserLoaded() {
if (!ready) {
// note the missing "()"
setTimeout(browserLoaded, 1000);
}
}
//this is a simple "semaphore" pattern:
var things_to_load_count = 1
var check_if_done(){
things_to_load_count--;
if(things_to_load_count <= 0){
//code to do stuff after you finish loading
}
};
$(_response).find('ACTION').each(function() {
if (tagName=="RESOURCEUPDATE") {
things_to_load_count++;
run_code_to_load_stuff( check_if_done )
//make sure that the run_code_to_load_stuff function
//calls the callback you passed it once its done.
} else if (tagName=="EVENT") {
//process one of the normal nodes
}
});
//this will run the remaining code if we loaded everything
//but will do nothing if we are still waiting.
check_if_done()
var resources = [];
$(_response).find('ACTION').each(function() {
var deferred = resources.length > 0 ? resources[resources.length - 1] : null;
switch (tagName) {
case "RESOURCEUPDATE":
deferred = $.Deferred();
//load the resource with selected id in an iframe
$(iframe).bind('load', function () {
deferred.resolve(/*specific arg1, arg2, arg3, ...*/)
});
resources.push(deferred);
break;
case "EVENT":
if (deferred) {
deferred.done(function (/*specific arg1, arg2, arg3, ...*/) {
// process event node
});
}
break;
}
});
// clean up deferreds objects when all them will be processed
$.when.apply($, resources).then(function() {
resources.length = 0;
})
等待功能是:
function browserLoaded() {
if (!ready) {
setTimeout(browserLoaded(),1000);
}
}
当加载iframe时,ready var变为true:
$(iframe).load(function() {
ready = true;
});
但当执行时,我将捕获此错误:
Maximum call stack size exceeded error
有什么想法吗?
谢谢 问题出在这个函数中,它调用自己直到堆栈满:
function browserLoaded() {
if (!ready) {
//here you call browserLoaded function instead of passing a reference to the function
setTimeout(browserLoaded() ,1000);
}
}
您的函数应该如下所示:
[...]
<action>
<resource update>id</resourceupdate>
</action>
<action>
<event>id1</event>
</action>
<action>
<event>id2</event>
</action>
<action>
<event>id3</event>
</action>
[...]
function browserLoaded() {
if (!ready) {
// note the missing "()"
setTimeout(browserLoaded, 1000);
}
}
//this is a simple "semaphore" pattern:
var things_to_load_count = 1
var check_if_done(){
things_to_load_count--;
if(things_to_load_count <= 0){
//code to do stuff after you finish loading
}
};
$(_response).find('ACTION').each(function() {
if (tagName=="RESOURCEUPDATE") {
things_to_load_count++;
run_code_to_load_stuff( check_if_done )
//make sure that the run_code_to_load_stuff function
//calls the callback you passed it once its done.
} else if (tagName=="EVENT") {
//process one of the normal nodes
}
});
//this will run the remaining code if we loaded everything
//but will do nothing if we are still waiting.
check_if_done()
var resources = [];
$(_response).find('ACTION').each(function() {
var deferred = resources.length > 0 ? resources[resources.length - 1] : null;
switch (tagName) {
case "RESOURCEUPDATE":
deferred = $.Deferred();
//load the resource with selected id in an iframe
$(iframe).bind('load', function () {
deferred.resolve(/*specific arg1, arg2, arg3, ...*/)
});
resources.push(deferred);
break;
case "EVENT":
if (deferred) {
deferred.done(function (/*specific arg1, arg2, arg3, ...*/) {
// process event node
});
}
break;
}
});
// clean up deferreds objects when all them will be processed
$.when.apply($, resources).then(function() {
resources.length = 0;
})
这是一个糟糕的设计。您不需要“等待”超时机制。如果您是通过jqueryajax请求加载页面,请使用回调函数继续执行代码(您也许可以跟踪正在处理的“当前”项并继续执行下一个)。如果您正在加载iFrame,这也是一个糟糕的设计,那么您应该转向jQuery ajax方式。一个快速的技巧就是设置一个轮询循环:使用setInterval每隔一段时间检查一次变量是否已设置,然后使用clearInterval并在指定时间继续执行 不管怎样,做事都会很痛苦。本质上,用Javascript告诉某些东西运行后者的唯一方法是将其打包到函数中。但这样做之后,它会变得更容易,因为您可以传递该函数,并在完成后让异步代码调用它 例如,您的处理可能如下所示:
[...]
<action>
<resource update>id</resourceupdate>
</action>
<action>
<event>id1</event>
</action>
<action>
<event>id2</event>
</action>
<action>
<event>id3</event>
</action>
[...]
function browserLoaded() {
if (!ready) {
// note the missing "()"
setTimeout(browserLoaded, 1000);
}
}
//this is a simple "semaphore" pattern:
var things_to_load_count = 1
var check_if_done(){
things_to_load_count--;
if(things_to_load_count <= 0){
//code to do stuff after you finish loading
}
};
$(_response).find('ACTION').each(function() {
if (tagName=="RESOURCEUPDATE") {
things_to_load_count++;
run_code_to_load_stuff( check_if_done )
//make sure that the run_code_to_load_stuff function
//calls the callback you passed it once its done.
} else if (tagName=="EVENT") {
//process one of the normal nodes
}
});
//this will run the remaining code if we loaded everything
//but will do nothing if we are still waiting.
check_if_done()
var resources = [];
$(_response).find('ACTION').each(function() {
var deferred = resources.length > 0 ? resources[resources.length - 1] : null;
switch (tagName) {
case "RESOURCEUPDATE":
deferred = $.Deferred();
//load the resource with selected id in an iframe
$(iframe).bind('load', function () {
deferred.resolve(/*specific arg1, arg2, arg3, ...*/)
});
resources.push(deferred);
break;
case "EVENT":
if (deferred) {
deferred.done(function (/*specific arg1, arg2, arg3, ...*/) {
// process event node
});
}
break;
}
});
// clean up deferreds objects when all them will be processed
$.when.apply($, resources).then(function() {
resources.length = 0;
})
//这是一个简单的“信号量”模式:
var things\u to\u load\u count=1
var check_if_done(){
东西要装多少;
如果(things\u to\u load\u count使用某种标志确实是个坏主意。您必须使用延迟模式。类似于以下内容:
[...]
<action>
<resource update>id</resourceupdate>
</action>
<action>
<event>id1</event>
</action>
<action>
<event>id2</event>
</action>
<action>
<event>id3</event>
</action>
[...]
function browserLoaded() {
if (!ready) {
// note the missing "()"
setTimeout(browserLoaded, 1000);
}
}
//this is a simple "semaphore" pattern:
var things_to_load_count = 1
var check_if_done(){
things_to_load_count--;
if(things_to_load_count <= 0){
//code to do stuff after you finish loading
}
};
$(_response).find('ACTION').each(function() {
if (tagName=="RESOURCEUPDATE") {
things_to_load_count++;
run_code_to_load_stuff( check_if_done )
//make sure that the run_code_to_load_stuff function
//calls the callback you passed it once its done.
} else if (tagName=="EVENT") {
//process one of the normal nodes
}
});
//this will run the remaining code if we loaded everything
//but will do nothing if we are still waiting.
check_if_done()
var resources = [];
$(_response).find('ACTION').each(function() {
var deferred = resources.length > 0 ? resources[resources.length - 1] : null;
switch (tagName) {
case "RESOURCEUPDATE":
deferred = $.Deferred();
//load the resource with selected id in an iframe
$(iframe).bind('load', function () {
deferred.resolve(/*specific arg1, arg2, arg3, ...*/)
});
resources.push(deferred);
break;
case "EVENT":
if (deferred) {
deferred.done(function (/*specific arg1, arg2, arg3, ...*/) {
// process event node
});
}
break;
}
});
// clean up deferreds objects when all them will be processed
$.when.apply($, resources).then(function() {
resources.length = 0;
})
p.S.:您确定在iframe加载函数中设置为true的ready变量与在调用另一个settimeout之前检查的变量相同。似乎iframe加载函数中的一个是局部变量,另一个是全局变量
或者两个就绪变量都是本地变量。setTimeout(browserLoaded(),1000);
执行您的函数。您只需引用您的函数;删除()
,使其成为setTimeout(browserLoaded,1000)
感谢您的快速响应!好的,没有更多错误,但执行不会停止。我大大简化了代码,使其不包含不必要的信息。实际上,iframe的load函数包含多个处理程序,用于截获用户交互并将xml消息发送到servlet。这将存储这些消息,并或多或少地将它们发送给其他客户端用异步回调函数Get on through的语法表示(简化)我不能在iframe加载的回调中处理消息,因为这些消息是异步的,不一定到达加载iframehm,你不能至少利用iframe的onLoad事件吗?不处理消息,但最多触发一个变量(ready):(如果你能触发一个变量(在iFrame的父级中)还应该能够调用函数。例如:[iFrame onLoad='parent.continueWithNextOne();']这难道不可能吗?如果iframe和父级在同一个域中,这应该是可能的?我不确定消息是否按此顺序到达,它可能会变得更公平。我认为这样的设计是不好的。同样地编写两个代码分支。上面解释的情况是一个特殊情况,我不会推翻特定情况下的代码有趣的是,我会看一看这是正确的答案;代码并不完全是我所需要的,但是关于延迟的建议让我找到了解决问题的最佳解决方案。thanksi declare var ready=true在我的core.js开头(在任何分支或函数之外);在我只做了赋值之后,从不在其他地方声明变量。