“封锁”;“等等”;javascript中的函数?
作为我正在进行的Javascript项目的一部分,有一些同步ajax调用(我想这就是“sjax”,但我离题了)。我现在正在编写一个调试面板,它允许我通过包装“封锁”;“等等”;javascript中的函数?,javascript,jquery,ajax,sjax,Javascript,Jquery,Ajax,Sjax,作为我正在进行的Javascript项目的一部分,有一些同步ajax调用(我想这就是“sjax”,但我离题了)。我现在正在编写一个调试面板,它允许我通过包装$.ajax,使用一些人工模拟的网络条件测试站点。简单的事情:假装500个响应等等,让ajax调用花费更长的时间 对于异步调用,这很简单。当实际响应返回时,添加一个setTimeout,使其在触发回调之前等待人工响应时间。然而,这显然不适用于同步调用,因为setTimeout不是同步的 那么,有没有办法让Javascript程序在设定的时间内
$.ajax
,使用一些人工模拟的网络条件测试站点。简单的事情:假装500个响应等等,让ajax调用花费更长的时间
对于异步调用,这很简单。当实际响应返回时,添加一个setTimeout
,使其在触发回调之前等待人工响应时间。然而,这显然不适用于同步调用,因为setTimeout
不是同步的
那么,有没有办法让Javascript程序在设定的时间内执行阻塞等待
我唯一能想到的就是这样的事情:
function wait(ms) {
var start = +(new Date());
while (new Date() - start < ms);
}
函数等待(毫秒){
var start=+(新日期());
while(新日期()-开始<毫秒);
}
有更好的解决办法吗
(另外,请假设有一个很好的理由阻止ajax调用…
:-\
)不要在JavaScript级别执行此操作。获取代理,如,并设置一个,以将呼叫延迟一段时间 如果只是为了调试目的而进行人工延迟:
alert('block me one more time');
没有其他合理的方法可以在ECMAscript中使用阻塞代码。由于Javascript是在浏览器用来呈现DOM和某些其他东西的同一个线程(“UI线程”)中执行的,所以整个节目的设计并不是为了阻止任何东西
当然,你可以通过使用循环来伪装它,但这是对表演的曲解。我想这段代码可能会有所帮助
// 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()
哈哈哈哈哈“sjax”+卢尔兹一人。XDDDD您现在有哪些代码不起作用?服务器端代码在您的控制之下吗?如果是这样,您可以添加一个请求参数(比如
delay
),并在发送响应之前让处理程序线程睡眠delay
秒。您可以发出警报,但除此之外(当然还有实际的同步ajax),浏览器不喜欢等待。您的等待功能是(或多或少)在JS中执行阻塞等待的常用方法(例如:)。但是,正如下面所建议的,在这种情况下,代理可能是更好的方法。这确实会阻止,但不会提供任何类似于精确控制持续时间的功能。
// // // 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 // // //