javascript - Node.js:如何在不阻塞事件循环的情况下重新创建 'setTimeout' 函数?

标签 javascript node.js

我进行了大量搜索,试图找出如何在 Node.js 中创建非阻塞代码。不幸的是,我发现的每个示例都基于一个函数,该函数最终已经具有内置回调。所以我想用回调创建我自己的函数,但由于某种原因它阻止了事件循环。这并没有阻止事件循环:

function foo(response){
    setTimeout(function(){
        response.writeHead(200, {"Content-Type": "text/plain"});
        response.write("bar");
        response.end();
    }, 7000);
}

但是这样做了:

function foo(response){
    function wait(callback, delay){
            var startTime = new Date().getTime();
        while (new Date().getTime() < startTime + delay);
        callback();
    }
    wait(function(){
        response.writeHead(200, {"Content-Type": "text/plain"});
        response.write("bar");
        response.end();
    }, 7000);
}

我缺少非阻塞代码的哪些基本方面?

编辑:

我想重新创建 setTimeout 的目标更像是一种脑力练习,我想我会尝试这样我可以更好地理解偶数循环。现在我担心如果我有一些相当繁重的服务器端代码在 JavaScript 中进行一些原始处理,我不知道如何阻止它停止我的事件循环。

在阅读了您的回答并进一步思考之后,我认为更准确的问题可能是:如果我在服务器上使用 JavaScript 进行繁重的处理,我该如何阻止它中断事件循环?

这是我第一次在这里发帖,所以我不知道我会得到什么样的回应。到目前为止,这太棒了。谢谢,伙计们。

编辑 2: 嘿,再次感谢大家的建议。我最终像 Raynos 建议的那样尝试了 process.nextTick ......而且它奏效了!我设法通过回调创建了自己的非阻塞计时器。代码并不完美,但对于那些好奇的人来说,它看起来是这样的:

var timer = {};

function delay(callback, length){
    if(!timer.startTime){
        timer.startTime = new Date().getTime();
        timer.callback = callback;
        timer.length = length;
    }
    if(new Date().getTime() < timer.startTime + timer.length){
        process.nextTick(delay);
    } else {
        timer.callback();
        timer = {};
    }
}

function list(response){
    delay(function(){
        console.log("callback");
        exec("dir", function (error, stdout, stderr) {
            response.writeHead(200, {"Content-Type": "text/plain"});
            response.write(stdout);
            response.end();
        });
    }, 7000);
}

不是真的打算使用此代码。但是学习如何执行此操作的过程无疑帮助我理解了有关非阻塞的一些关键概念。

对于那些仍然对非阻塞感到好奇的人,您应该查看 Raynos' article.

最佳答案

为了不阻塞事件循环,您的代码必须最终返回到事件循环并允许它继续处理。除非您的代码实际上返回到事件循环,否则它无法使下一条消息出列并处理它。此代码不会在给定时间段内退出,因此永远不会将控制权返回给事件循环。

关于javascript - Node.js:如何在不阻塞事件循环的情况下重新创建 'setTimeout' 函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8949465/

相关文章:

node.js - 使用 bull 进行作业处理微服务

javascript - 如何使用 Thinktecture.IdentityServer.v2 和 Node.js 来实现 WS-Federation?

node.js - Websockets - 自定义排队系统有意义吗?

javascript - 为什么 .findByIdAndUpdate 会绕过 mongoose 中间件?

javascript - 仅在选定模式下更改选定选项的文本

javascript - 我怎样才能 "word wrap"容器 div 中的 div?

javascript - 防止在后台滚动

javascript - 无法捕获从 Angular 4 中的子组件发出的事件

javascript - 如何将处理程序附加到动态加载的链接?

javascript - 发布功能完成后重新加载