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

时间:2018-04-04 15:59:07

标签: javascript node.js asynchronous callback event-loop

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

我知道Node.js中的几乎每个函数都是异步的。 我认为我们的节点函数是以这种方式编写的,因此指针赋值发生在事件循环中。 (Node.js高达Posix单线程)。 因此,事件循环(借助于编写的异步函数)允许节点js运行非块。

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

问题1:我们应该异步编写我们在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);
});

为什么?

感谢您的启发答案。 你能否就这个话题向我推荐任何文献或教育。

感谢。

1 个答案:

答案 0 :(得分:0)

process.nextTick()setTimeout()之类的功能实际上并不会使代码异步运行。相反,它们会改变代码运行的时间,但是当它运行时它仍然是同步的。因此,您可以使用这些功能在某些事情运行一段时间后推迟。例如,在你的sum()函数中,如果那个巨型for循环运行5秒钟,无论你是立即运行还是运行它,它仍会阻止事件循环5秒是否在使用process.nextTick()setTimeout()运行时推迟。所有这些功能在运行时都会发生变化。有时候改变运行时间是合乎需要的,但它并没有做出非阻塞的事情。

您无法在纯Javascript中实际编写一个从头开始的异步函数。 node.js中的Javascript是单线程的,因此根据定义,您编写的任何Javascript都不会在后台运行。要真正异步,异步函数必须实际利用本机代码,它可以使用线程或非阻塞的OS函数。

因此,要实际异步运行for循环(其他Javascript可以在for循环运行的同时运行),您必须使用本机代码在线程中使用本机代码运行它或者启动子node.js进程以在另一个node.js进程中运行它并让操作系统管理并发。

当然,您可以编写调用已经使用本机代码编写的异步函数的Javascript(fshttp模块中的此类函数),但即便如此,如果您有任何时间在你的Javascript中消费(比如处理一个大的结果),这仍然需要时间,而其他Javascript无法运行,而你正在运行大量结果的Javascript处理。

异步代码的编写,测试和调试总是比同步代码更复杂。所以,你很少想要采取实际阻塞和同步的东西,并把它放在异步API之后,因为这会使事情变得比需要的更复杂。

如果您需要使用process.nextTick()setTimeout()来安排某些事情在将来运行一段时间,那就完全没问题了,那么将它置于一个承诺界面之后是有意义的。

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