在javascript中阻止“等待”function?

作为我正在研究的Javascript项目的一部分,有一些同步的ajax调用(我猜这使它成为“sjax”,但我离题了) 。 我现在正在编写一个调试面板,它允许我通过包装$.ajax来测试一些人工模拟的网络条件。 简单的事情:伪造500响应等,并使ajax调用需要更长的时间。

对于异步调用,它很简单。 当真实响应返回时,添加一个setTimeout以使其在触发回调之前等待人工响应时间。 但是,这显然不适用于同步调用,因为setTimeout不是同步的。

那么,有没有办法让Javascript程序执行阻塞等待一段时间?

我唯一能想到的就是这样的事情:

 function wait(ms) { var start = +(new Date()); while (new Date() - start < ms); } 

有更好的解决方案吗?

(另外,请假设有一个很好的理由阻止ajax调用…… :-\

不要在JavaScript级别上执行此操作。 获取Fiddler等代理并设置AutoResponder以将呼叫延迟一段时间。

如果只是出于调试目的而产生人为延迟:

 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; //  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() 

并测试……

 // // // 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 // // //