Javascript Nodejs中的非阻塞事件循环

Javascript Nodejs中的非阻塞事件循环,javascript,node.js,concurrency,eventqueue,Javascript,Node.js,Concurrency,Eventqueue,我试图实现一个事件循环。循环的目的很简单: 如果队列不是空的,则让task成为队列中最早的条目 过程任务 如果任务生成返回值,则缓存它 检查队列中的任务 如果队列不为空,则采用下一个任务作为当前任务上下文 将缓存的返回值传递给新任务 我以以下方式在Nodejs中尝试了一个实现: function task(){ this.task = Array.prototype.shift.call(arguments); this.state = 'unprocessed'; this.successCa

我试图实现一个事件循环。循环的目的很简单:

  • 如果队列不是空的,则让task成为队列中最早的条目
  • 过程任务
  • 如果任务生成返回值,则缓存它
  • 检查队列中的任务
  • 如果队列不为空,则采用下一个任务作为当前任务上下文
  • 将缓存的返回值传递给新任务
  • 我以以下方式在Nodejs中尝试了一个实现:

    function task(){
    this.task = Array.prototype.shift.call(arguments);
    this.state = 'unprocessed';
    this.successCallback = null;
    this.failureCallback = null;
    }
    task.prototype.afterThat = function(){
    if(arguments.length > 1){
    this.successCallback = Array.prototype.shift.call(arguments);
    this.failureCallback = Array.prototype.shift.call(arguments);
    }
    }
    task.prototype._loop = function(){
    let ctx = this;
    while(ctx.state === 'unprocessed'){ // Source of problem
        setImmediate(this.task, function(){
        // change ctx.state if needed
       }, function(){
       // change ctx.state to 'processed'
       });
     }
    }
    
    此实现与事件循环实现之间的区别如下:

  • successCallback可以实例化一个新任务作为其返回,然后将其作为当前任务,而不是维护一个任务数组
  • 根据处理情况,任务状态必须更改(如果采用了状态为“未处理”的新挂起任务,则不更改) 我认为问题在于setImmediate调用,它无法更改上下文状态,因为当前的执行状态从未终止,并不断在事件队列中为同一任务添加新调用

    我希望我已经很好地解释了这一点,并将感谢一些实现指南,以及我在理解事件队列时可能遇到的任何错误


    谢谢。

    您的
    ,而
    循环是一个无限循环。JS是单线程的,因此在
    while
    循环完成之前,其他任何东西都不能运行。因为没有其他东西可以运行,
    ctx.state
    将永远不会更改。因为
    ctx.state
    永远无法更改,所以
    while
    循环将永远运行

    每次循环运行时,它都会调用
    setImmediate()
    ,它会安排一个任务运行,但在
    while
    循环完成之前,该任务实际上无法运行。因此,您陷入僵局,并且将堆积大量要运行的任务列表(最终可能会溢出一些系统资源)

    在完成运行任务后(可能在成功和失败回调中),您需要检查
    ctx.state
    ,而不是在这样的循环中

    setImmediate()
    未阻塞。使用
    setImmediate()
    调度的函数在
    while
    循环完成之前不会运行,但
    while
    循环从未找到其条件,因此它从未停止,因为在
    while
    循环完成之前,其他任何操作都无法运行

    相反,调用下一个任务,完成后,检查
    ctx.state
    。由于您没有展示或描述如何使用它,或者您真正想要实现什么,我不确定建议的最佳实现。如果你想在这方面得到更多帮助,那么你需要向我们展示更多关于你想要完成什么以及你想如何使用这个类的信息

    我的猜测是,您可以使用承诺来完成您试图完成的任务,而不必自己编写太多的基础架构代码,因为承诺是异步任务排序的非常好的工具


    仅供参考,您的代码有几处错误,例如缺少右大括号和括号。您发布的内容甚至无法正确解析,更不用说运行了。并且,请在发布时正确缩进代码



    您的
    循环是一个无限循环。JS是单线程的,因此在
    while
    循环完成之前,其他任何东西都不能运行。因为没有其他东西可以运行,
    ctx.state
    将永远不会更改。因为
    ctx.state
    永远无法更改,所以
    while
    循环将永远运行

    每次循环运行时,它都会调用
    setImmediate()
    ,它会安排一个任务运行,但在
    while
    循环完成之前,该任务实际上无法运行。因此,您陷入僵局,并且将堆积大量要运行的任务列表(最终可能会溢出一些系统资源)

    在完成运行任务后(可能在成功和失败回调中),您需要检查
    ctx.state
    ,而不是在这样的循环中

    setImmediate()
    未阻塞。使用
    setImmediate()
    调度的函数在
    while
    循环完成之前不会运行,但
    while
    循环从未找到其条件,因此它从未停止,因为在
    while
    循环完成之前,其他任何操作都无法运行

    相反,调用下一个任务,完成后,检查
    ctx.state
    。由于您没有展示或描述如何使用它,或者您真正想要实现什么,我不确定建议的最佳实现。如果你想在这方面得到更多帮助,那么你需要向我们展示更多关于你想要完成什么以及你想如何使用这个类的信息

    我的猜测是,您可以使用承诺来完成您试图完成的任务,而不必自己编写太多的基础架构代码,因为承诺是异步任务排序的非常好的工具


    仅供参考,您的代码有几处错误,例如缺少右大括号和括号。您发布的内容甚至无法正确解析,更不用说运行了。并且,请在发布时正确缩进代码



    我建议更好地缩进代码。我相信你是在定义
    任务.prototype.\u loop
    任务.prototype.之后
    。你的
    循环是一个无限循环。JS是单线程的,因此由于您的
    while
    循环,其他任何东西都无法运行。完成任务运行后,需要检查
    ctx.state
    setImmediate()
    未阻塞。它不会运行,直到你的
    while
    循环完成,这是一个无限循环,所以它永远不会完成。我建议你的代码缩进得更好。我相信你是在定义
    任务.prototype.\u loop
    任务.prototype.之后
    。你的
    循环是一个无限循环。JS是单线程的,因此由于您的
    whi,其他任何东西都不能运行