我在我的代码中有一个长时间运行的循环,我想延迟这个循环以处理事件队列中的其他任务(例如按钮按下)。JavaScript或JQuery是否有任何可以帮助我的东西?基本上,我正在尝试像这样延迟循环 (https://support.microsoft.com/en-us/kb/118468)。
我在我的代码中有一个长时间运行的循环,我想延迟这个循环以处理事件队列中的其他任务(例如按钮按下)。JavaScript或JQuery是否有任何可以帮助我的东西?基本上,我正在尝试像这样延迟循环 (https://support.microsoft.com/en-us/kb/118468)。
var myWorker = new Worker("worker.js");
myWorker.postMessage([first.value,second.value]);
console.log('Message posted to worker');
请像这样响应worker.js
中的消息:
onmessage = function(e) {
console.log('Message received from main script');
var workerResult = 'Result: ' + (e.data[0] * e.data[1]);
console.log('Posting message back to main script');
postMessage(workerResult);
}
随着ES6中生成器的引入,您可以编写一个帮助方法,使用yield
来模拟DoEvents,而不需要太多的语法开销:
doEventsOnYield(function*() {
... synchronous stuff ...
yield; // Pump the event loop. DoEvents() equivalent.
... synchronous stuff ...
});
function doEventsOnYield(generator) {
return new Promise((resolve, reject) => {
let g = generator();
let advance = () => {
try {
let r = g.next();
if (r.done) resolve();
} catch (ex) {
reject(ex);
}
setTimeout(advance, 0);
};
advance();
});
}
setTimeout(function() { }, 3600);
3600是以毫秒为单位的时间:
没有与DoEvents
完全等价的东西。接近的方法是为每个迭代使用setTimeout
:
(function next(i) {
// exit condition
if (i >= 10) {
return;
}
// body of the for loop goes here
// queue up the next iteration
setTimeout(function () {
// increment
next(i + 1);
}, 0);
})(0); // initial value of i
然而,这很少是一个好的解决方案,在Web应用程序中几乎从来不需要。可能有一个你错过了的事件可以使用。你真正的问题是什么?
myWorker.postMessage([first.value,second.value]);
直到循环结束后才被执行。但我肯定会重新设计XHR请求的。 - Ph33ly这是一个经过测试的示例,演示如何使用Yield作为DoEvents的直接替代。
(我已经使用了Web Worker,它非常好用,但它与DoEvents相距甚远,几乎无法访问全局变量)。这个示例已经格式化以便于理解,并尝试展示如何将所需的额外功能(使函数处理yield)视为原始函数中的插入。 "yield"还有各种其他功能,但在这种情况下,它几乎可以直接替代DoEvents。
//'Replace DoEvents with Yield ( https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/yield )
var misc = 0; //'sample external var
function myfunction() { //'This is the beginning of your original function which is effectively replaced by a handler inserted as follows..
//'-----------------------------------Insert Handler..
var obj = myfuncGen.next(); //'start it
if (obj.done == false) {
setTimeout(myfunction, 150); //'adjust for the amount of time you wish to yield (depends how much screen drawing is required or etc)
}
}
var myfuncGen = myfuncSurrogate(); //'creates a "Generator" out of next.
function* myfuncSurrogate() { //'This the original function repackaged! Note asterisk.
//'-------------------------------------End Insert
var ms; //...your original function continues here....
for (var i = 1; i <= 9; i++) { //'sample 9x loop
ms = new Date().getTime();
while (new Date().getTime() < ms + 500); //'PAUSE (get time & wait 500ms) as an example of being busy
misc++; //'example manipulating an external var
outputdiv.innerHTML = "Output Div<br>demonstrating progress.. " + misc;
yield; //'replacement for your doevents, all internal stack state and variables effectively hibernate.
}
console.log("done");
}
myfunction(); //'and start by calling here. Note that you can use "return" to return a value except by call backs.
<div id='outputdiv' align='center'></div>
如果你对这些都是新手,要知道如果没有插入和yield关键字,你只会在什么也没发生的情况下等待5秒钟,然后进度{div}将显示“9”(因为对{div}的所有其他更改都是不可见的)。