在 Node.js 中创建自定义异步函数

Create custom asynchronous function in Node.js

我正在尝试学习异步逻辑,但脑子里有很多问题。

我知道 Node.js 中几乎每个函数都是异步的。 我认为我们的节点函数是这样写的,所以指针赋值发生在事件循环中。 (Node.js 到 Posix 单线程)。 所以事件循环(在编写的异步函数的帮助下)允许节点 js 运行 非阻塞。

据我所知,我们必须异步编写函数。(至少这会很有用)。

问题一:Node.js中写的函数应该异步写吗?如果我写了会有用吗?

如果是这样,对事件循环有帮助吗? 如果我们不异步写呢? (每秒一个功能或每分钟一个功能)

我了解到应该使用回调。然后我了解到使用回调(s:code1)无法实现异步。然后我了解到nextTick还是应该使用setTimeout这样的函数。 我们应该在 nodejs 中使用 nexttick yada settimeout 吗?

所以:code1:它是同步的

function sum(x, y, cb) {
  for (let index = 0; index < 100000000; index++) {}
  cb(x + y);
}

console.log(0);

sum(1, 2, cb => {
  console.log(cb);
});

console.log(10);

// 0, 3, 10

code2:它是异步使用(nextTick 或 setTimeout 无关紧要)。

function sum(x, y, cb) {
  process.nextTick(() => {
    for (let index = 0; index < 100000000; index++) {}
    cb(x + y);
  });
}

console.log(0);

sum(1, 2, cb => {
  console.log(cb);
});

console.log(10);
// 0, 10, 3

问题 2:不同 process.nextTick - setTimeOut

考试 1:这是同步

function sum(x, y, callback) {
  process.nextTick(() => {
    for (let index = 0; index < 10000000000; index++);
    callback(x + y);
  });
}

var mul = (x, y) =>
  new Promise((resolve, reject) => {
    resolve(x * y);
  });

sum(2, 3, cb => {
  console.log(cb);
});

mul(5, 5).then(cb => {
  console.log(cb);
});

考试 2:它是异步的

function sum(x, y, callback) {
  setTimeout(() => {
    for (let index = 0; index < 10000000000; index++);
    callback(x + y);
  }, 0);
}

var mul = (x, y) =>
  new Promise((resolve, reject) => {
    resolve(x * y);
  });

sum(2, 3, cb => {
  console.log(cb);
});

mul(5, 5).then(cb => {
  console.log(cb);
});

为什么?

感谢您富有启发性的回答。 你能给我推荐关于这个主题的任何文档或教育吗?

谢谢。

process.nextTick()setTimeout() 等函数实际上并不会异步生成代码 运行。相反,他们改变了代码 运行s 的时间,但当它 运行s 时它仍然是同步的。因此,您可以使用这些函数将 运行s 推迟到以后的某个时间。例如,在你的任何一个 sum() 函数中,如果那个巨大的 for 循环需要 5 秒到 运行,它仍然会阻塞事件循环 5 秒,无论你是否 运行 立即或是否在 运行 与 process.nextTick()setTimeout() 一起推迟。所有这些函数所做的就是在 运行 时发生变化。有时更改 运行 的时间是可取的,但它不会产生 non-blocking.

您实际上无法在纯 Javascript 中编写 from-scratch 异步函数。 node.js 中的 Javascript 是单线程的,因此根据定义,您编写的任何 Javascript 都不会在后台运行 运行。要真正异步,异步函数必须实际利用本机代码,它可以使用线程或 non-blocking OS 函数。

所以,实际上 运行 for 异步循环(你的另一个 Javascript 可以 运行 同时 for 循环是 运行ning),你必须要么使用本机代码 运行 它与线程中的本机代码,要么启动子 node.js 进程以 运行 它在另一个 node.js 处理并让 OS 管理并发。

当然,您可以编写 Javascript 来调用已经用本机代码编写的异步函数(此类函数在 fshttp 模块中),但即使那么如果你在你的 Javascript 中做任何耗时的事情(比如处理一个大的结果),那仍然需要时间而其他 Javascript 不能 运行 当你 运行宁 Javascript 处理那个大结果。


异步代码的编写、测试和调试总是比同步代码复杂得多。所以,你很少想把实际上阻塞和同步的东西放在异步 API 后面,因为这只会让事情变得比需要的更复杂。

如果您需要使用 process.nextTick()setTimeout() 将某些内容安排到 运行 将来的某个时间,那完全没问题,那么将其放在承诺接口。

但是,如果在 运行 时推迟对您的代码结构没有明显的好处,那么将它放在 promise 接口后面只会使它的使用更加复杂。同步代码更简单。我的 5 大编程规则之一是不要让任何东西变得比它需要的更复杂(通常称为 KISS - 保持简单愚蠢)。这适用于此。