[英]Blocking “wait” function in javascript?
As part of a Javascript project I'm working on, there are some synchronous ajax calls (I guess that makes it "sjax", but I digress) . 作为我正在研究的Javascript项目的一部分,有一些同步的ajax调用(我猜这使它成为“sjax”,但我离题了) 。 I'm now writing a debugging panel which would allow me to test out the site with some artificially simulated network conditions by wrapping
$.ajax
. 我现在正在编写一个调试面板,它允许我通过包装
$.ajax
来测试一些人工模拟的网络条件。 Simple things: faking a 500 response etc, and making the ajax calls take much longer. 简单的事情:伪造500响应等,并使ajax调用需要更长的时间。
For the asynchronous calls, it's simple. 对于异步调用,它很简单。 When the real response comes back, add a
setTimeout
to make it wait for the artificial response time before triggering the callback. 当真实响应返回时,添加一个
setTimeout
以使其在触发回调之前等待人工响应时间。 However, this doesn't work with the synchronous calls obviously, since setTimeout
isn't synchronous. 但是,这显然不适用于同步调用,因为
setTimeout
不是同步的。
So, is there a way to make a Javascript program perform a blocking wait for a set amount of time? 那么,有没有办法让Javascript程序执行阻塞等待一段时间?
The only thing I could think of would be something like this: 我唯一能想到的就是这样的事情:
function wait(ms) {
var start = +(new Date());
while (new Date() - start < ms);
}
Is there a better solution? 有更好的解决方案吗?
(Also, please assume there's a good reason for the blocking ajax calls... :-\\
) (另外,请假设有一个很好的理由阻止ajax调用......
:-\\
)
Do not do it on the JavaScript level. 不要在JavaScript级别上执行此操作。 Get a proxy such as Fiddler and set up an AutoResponder to delay the call by a time period.
获取Fiddler等代理并设置AutoResponder以延迟一段时间的呼叫。
If it's just for debugging purposes to have an artificial delay: 如果只是出于调试目的而产生人为延迟:
alert('block me one more time');
There is no reasonable other approach to have a blocking code in ECMAscript. 在ECMAscript中没有合理的其他方法来阻止代码。 Since Javascript is executed in the same thread ("UI thread") which browsers use to render the DOM and to certain other things, the whole show was designed not to block anything.
由于Javascript是在浏览器用来呈现DOM和某些其他东西的同一个线程(“UI线程”)中执行的,因此整个节目被设计为不阻止任何内容。
Of course you can fake it by using a loop, but its a perversion of the show. 当然你可以通过使用循环伪造它,但它是对节目的歪曲。
I figured this code might help 我认为这段代码可能有所帮助
// execute code consecutively with delays (blocking/non-blocking internally)
function timed_functions()
{
this.myfuncs = [];
this.myfuncs_delays = []; // mirrors keys of myfuncs -- values stored are custom delays, or -1 for use default
this.myfuncs_count = 0; // increment by 1 whenever we add a function
this.myfuncs_prev = -1; // previous index in array
this.myfuncs_cur = 0; // current index in array
this.myfuncs_next = 0; // next index in array
this.delay_cur = 0; // current delay in ms
this.delay_default = 0; // default delay in ms
this.loop = false; // will this object continue to execute when at end of myfuncs array?
this.finished = false; // are we there yet?
this.blocking = true; // wait till code completes before firing timer?
this.destroy = false; // <advanced> destroy self when finished
// handle next cycle execution
this.next_cycle = function() {
var that = this;
var mytimer = this.delay_default;
if(this.myfuncs_cur > -1)
if(this.myfuncs_delays[this.myfuncs_cur] > -1)
mytimer = this.myfuncs_delays[this.myfuncs_cur];
console.log("fnc:" + this.myfuncs_cur);
console.log("timer:" + mytimer);
console.log("custom delay:" + this.myfuncs_delays[this.myfuncs_cur]);
setTimeout(function() {
// times up! next cycle...
that.cycle();
}, mytimer);
}
this.cycle = function() {
// now check how far we are along our queue.. is this the last function?
if(this.myfuncs_next + 1 > this.myfuncs_count)
{
if(this.loop)
{
console.log('looping..');
this.myfuncs_next = 0;
}
else
this.finished = true;
}
// first check if object isn't finished
if(this.finished)
return false;
// HANDLE NON BLOCKING //
if(this.blocking != true) // blocking disabled
{
console.log("NOT BLOCKING");
this.next_cycle();
}
// set prev = current, and current to next, and next to new next
this.myfuncs_prev = this.myfuncs_cur;
this.myfuncs_cur = this.myfuncs_next;
this.myfuncs_next++;
// execute current slot
this.myfuncs[this.myfuncs_cur]();
// HANDLE BLOCKING
if(this.blocking == true) // blocking enabled
{
console.log("BLOCKING");
this.next_cycle();
}
return true;
}; // END :: this.cycle
// adders
this.add = {
that:this,
fnc: function(aFunction) {
// add to the function array
var cur_key = this.that.myfuncs_count++;
this.that.myfuncs[cur_key] = aFunction;
// add to the delay reference array
this.that.myfuncs_delays[cur_key] = -1;
}
}; // end::this.add
// setters
this.set = {
that:this,
delay: function(ms) {
var cur_key = this.that.myfuncs_count - 1;
// this will handle the custom delay array this.that.myfunc_delays
// add a custom delay to your function container
console.log("setting custom delay. key: "+ cur_key + " msecs: " + ms);
if(cur_key > -1)
{
this.that.myfuncs_delays[cur_key] = ms;
}
// so now we create an entry on the delay variable
}, // end :: this.set.delay(ms)
delay_cur: function(ms) { this.that.delay_cur = ms; },
delay_default: function(ms) { this.that.delay_default = ms; },
loop_on: function() { this.that.loop = true; },
loop_off: function() { this.that.loop = false; },
blocking_on: function() { this.that.blocking = true; },
blocking_off: function() { this.that.blocking = false; },
finished: function(aBool) { this.that.finished = true; }
}; // end::this.set
// getters
this.get = {
that:this,
delay_default: function() { return this.that.delay_default; },
delay_cur: function() { return this.that.delay_cur; }
}; // end::this.get
} // end ::: timed_functions()
And Test... 并测试......
// // // BEGIN :: TEST // // //
// initialize
var fncTimer = new timed_functions;
// set some defaults
fncTimer.set.delay_default(1000); // set a default delay between function blocks
fncTimer.set.blocking_on(); // next timer begins count before code is executed
fncTimer.set.blocking_off(); // next timer begins count after code is executed
// fncTimer.set.loop_on(); // when finished start over
// fncTimer.set.loop_off();
// BEGIN :: ADD FUNCTIONS (they will fire off in order)
fncTimer.add.fnc(function() {
console.log('plan a (2 secs)');
});
fncTimer.set.delay(2000); // set custom delay for previously added function
fncTimer.add.fnc(function() {
console.log('hello world (delay 3 seconds)');
});
fncTimer.set.delay(3000);
fncTimer.add.fnc(function() {
console.log('wait 4 seconds...');
});
fncTimer.set.delay(4000);
// END :: ADD FUNCTIONS
// NOW RUN
fncTimer.cycle(); // begin execution
// // // END :: TEST // // //
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.