我正在尝试学习异步逻辑,我脑子里有很大的问题。
我知道Node.js中的几乎每个函数都是异步的。 我认为我们的节点函数是以这种方式编写的,因此指针赋值发生在事件循环中。 (Node.js高达Posix单线程)。 因此,事件循环(借助于编写的异步函数)允许节点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
考试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);
});
为什么?
感谢您的启发答案。 你能否就这个话题向我推荐任何文献或教育。
感谢。
答案 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(fs
或http
模块中的此类函数),但即便如此,如果您有任何时间在你的Javascript中消费(比如处理一个大的结果),这仍然需要时间,而其他Javascript无法运行,而你正在运行大量结果的Javascript处理。
异步代码的编写,测试和调试总是比同步代码更复杂。所以,你很少想要采取实际阻塞和同步的东西,并把它放在异步API之后,因为这会使事情变得比需要的更复杂。
如果您需要使用process.nextTick()
或setTimeout()
来安排某些事情在将来运行一段时间,那就完全没问题了,那么将它置于一个承诺界面之后是有意义的。
但是,如果你的代码结构在运行时推迟没有明显的好处,那么将它放在promise接口之后只会使它更复杂。同步代码更简单。编程的前5条规则之一就是不要做任何比它需要更复杂的事情(通常称为KISS - 保持简单愚蠢)。这适用于此。