Javascript Node.js:允许在循环期间更新进程

Javascript Node.js:允许在循环期间更新进程,javascript,node.js,Javascript,Node.js,我不清楚nodeJS中如何允许流程更新,例如: var cancelled = false; setTimeout(() => cancelled = true,1000); function main() { var ret = [] var totalStart =Date.now(); for(var i=0;i<20;i++) { var v v

我不清楚nodeJS中如何允许流程更新,例如:

    var cancelled = false;

    setTimeout(() => cancelled = true,1000);
    function main()
    {
        var ret = []
        var totalStart =Date.now(); 
        for(var i=0;i<20;i++) {
            var v
            var start =  Date.now();
            while((Date.now()-start)<100)
            {
                v = Math.sqrt(Math.random());
            }
            ret.push(v);
            if(cancelled) break;
        }
        console.log("delta:"+(Date.now()-totalStart));
        return ret;
    }

    var r = main()
    console.log(r.length)
var cancelled=false;
setTimeout(()=>cancelled=true,1000);
函数main()
{
var ret=[]
var totalStart=Date.now();

for(var i=0;i
setTimeout
是异步的。这意味着,除其他外,事件循环在堆栈为空之前不会将其处理程序放在队列上

因此,
setTimeout
需要两个条件才能将其处理程序放入队列(也称为运行它): 1.从
setTimeout
调用开始经过一秒钟。 2.堆栈为空

这两个条件是必需的。
setTimeout(handler,1000)
确保在一秒钟之前不会调用处理程序,但根本不能确保它在一秒钟之后运行

另一方面,for和while循环是阻塞的,也就是说,它们不允许事件循环将内容放在堆栈上。因此,在for循环停止之前,不会调用处理程序

还有一个问题与你的问题非常相似,肯定会对你有所帮助:

然而,我不认为这是完全重复的,一些额外的解释真的会帮助你

这段关于事件循环的youtube视频真的帮助我理解了这些东西:

另外,这篇nodejs文档文章也非常好:

来自

时间值表示(最小值)延迟,在此之后消息将实际推入队列。如果队列中没有其他消息,则消息将在延迟后立即处理;但是,如果有消息,setTimeout消息将必须等待其他消息被处理。。因此,第二个参数表示一个小参数妈妈的时间不是保证的时间

由于for循环占用了主线程,因此在循环结束之前,不会处理来自setTimeout的消息

因此,
0
的超时也会提供相同的输出

setTimeout(() => cancelled = true, 0);

经过一些测试,这段代码以我可以接受的方式工作

function AsyncLoop(start,to,fn,endFn) {
    return new Promise((resolve, reject) => {
       function Step(i) {
          var willContinue = fn(i);
          if(i==to || !willContinue) {
             if(endFn)
                 endFn(resolve, reject);
             else
                 resolve();

             return;
          }
          setImmediate(Step.bind(null,i+1));
       }
       Step(start);
    });
 }


var cancelled = false;

setTimeout(() => { console.log("cancel"); cancelled = true},1100);
var totalStart =Date.now(); 
var ret=[];
AsyncLoop(0,20, (idx) => {
    var start =  Date.now();
    while((Date.now()-start)<100) {
       v=Math.sqrt(Math.random());
    }
    ret.push(v);
    console.log("step "+idx+":"+v);
    return !cancelled;
}, (res)=>{
    res(ret);
    return 
}).then((r)=>{
    console.log("delta:"+(Date.now()-totalStart));
    console.log(r.length)   
 });
函数异步循环(开始、结束、结束){
返回新承诺((解决、拒绝)=>{
功能步骤(i){
var willContinue=fn(i);
如果(i==到| |!将继续){
如果(endFn)
endFn(决定、拒绝);
其他的
解决();
返回;
}
setImmediate(步骤绑定(null,i+1));
}
步骤(开始);
});
}
var=false;
setTimeout(()=>{console.log(“取消”);cancelled=true},1100);
var totalStart=Date.now();
var-ret=[];
异步循环(0,20,(idx)=>{
var start=Date.now();
while((Date.now()-start){
res(ret);
返回
})。然后((r)=>{
log(“delta:”+(Date.now()-totalStart));
console.log(r.length)
});

仍然没有答案的可能重复,为什么node没有一种简单的方法将sync函数转换为async,可能会添加一个像DoEvents()这样的函数?
setTimeout
没有说“停止每个线程,在超时结束时立即运行超时回调”,它只是说“这是我在事件循环有处理时间后尝试执行回调之前应该等待的最短时间。”
for
语句正在阻塞,
而循环正在阻塞