javascript - 陷入理解 Node js 的异步行为

标签 javascript node.js asynchronous ecmascript-6

我正在从 this site. 学习 Node js 回调和异步行为根据给出的示例,我编写了以下代码以更好地理解它。

function callbackTester (callbackFn){
    console.log('From callback tester.');
    callbackFn();
}

function pollingWait(){
    while (true) {}
}

callbackTester(() => {
    console.log('From anonymous function.');
    setTimeout(()=>{
        console.log("I'm waiting!");
    }, 500);
    // pollingWait();
});
console.log('I am the last one');

现在,当我注释掉 pollingWait() 函数时,它会按预期工作。它给出以下输出:

From callback tester.
From anonymous function.
I am the last one
I'm waiting!

现在,当我注释掉 setTimeout 函数并添加 pollingWait() 时,程序会进入无限循环。我认为这也是预期的行为,因为 Node js 是单线程的,无法避免无限循环。那么这种异步行为在幕后是如何工作的呢?

它如何决定何时继续执行、何时不继续执行?是否可以使我自己的函数像 setTimeout 一样充当异步函数?

最佳答案

I think this is also an expected behavior as node js is single threaded and cannot avoid infinite loops.

Node.js isn't single-threaded anymore ,但是除非您创建工作线程,否则只有一个主线程。

So how this asynchronous behavior works under the hood?

Node.js 的主线程在循环上工作:顶层代码运行并返回,然后任何排队的操作(例如计时器回调)运行并返回,然后下一个排队的操作运行并返回,等等。这就是 setTimeout 的工作原理:当计时器需要触发时,事件循环会看到这一点,并将对计时器回调的调用排队。另请注意,虽然 Node.js 默认情况下只有一个主 JavaScript 线程,但这并不意味着 Node 本身是单线程的。特别是它可以在另一个内部线程上进行 I/O 处理。

Is it possible to make my own function which acts as asynchronous like setTimeout?

只能使用已经提供异步行为的东西并将其包装起来。这些包括:

  • setTimeout
  • 立即设置
  • process.nextTick
  • promise 的 thencatch 回调

乍一看,您可能会认为 async 函数可以做到这一点,但实际上并非如此:async 函数中的代码同步运行 直到第一次等待 promise 决议(或直到它返回)。因此,异步性实际上与上面的最后一个要点相同:thencatch 回调。

不能做的(没有工作线程)是像你的pollingWait那样的忙等待,因为在忙等待的线程上不会发生任何其他事情正在运行。

关于javascript - 陷入理解 Node js 的异步行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53208302/

相关文章:

node.js - 如何在 Express 的多个文件中包含路由处理程序?

node.js - Socket.io:如何使用 Socket.io-redis 适配器计算房间中的客户端

node.js - node_modules/bcrypt/node_modules/bindings/bindings.js :83

c# 使用管道获取输出流

c# - 在UI线程上异步调用同步方法

javascript - Jquery,返回id

javascript - 带有 UI Bootstrap 指令的 ng-bind-html

javascript - setTimeout 方法的工作方式很奇怪

javascript - 要求子类实现方法而不是公开的

c# - 如何循环调用 C# HttpClient 中的分页 URL 以从 JSON 结果下载所有页面