Javascript 一直在理解节点js的异步行为
我正在学习NodeJS回调和异步行为,从给出的示例中,我编写了以下代码来更好地理解它Javascript 一直在理解节点js的异步行为,javascript,node.js,asynchronous,ecmascript-6,Javascript,Node.js,Asynchronous,Ecmascript 6,我正在学习NodeJS回调和异步行为,从给出的示例中,我编写了以下代码来更好地理解它 function callbackTester (callbackFn){ console.log('From callback tester.'); callbackFn(); } function pollingWait(){ while (true) {} } callbackTester(() => { console.log('From anonymous f
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()
时,程序进入无限循环。我认为这也是一种预期的行为,因为节点js是单线程的,无法避免无限循环。那么,这种异步行为在幕后是如何工作的呢
它如何决定何时继续执行,何时不继续执行?有没有可能让我自己的函数像setTimeout
那样起异步作用?
我认为这也是一种预期的行为,因为节点js是单线程的,无法避免无限循环
但是只有一个主线程,除非您创建辅助线程
那么,这种异步行为在幕后是如何工作的呢
Node.js的主线程在循环中工作:顶级代码运行并返回,然后任何排队操作(如计时器回调)运行并返回,然后下一个排队操作运行并返回,等等。这就是setTimeout
的工作方式:当计时器启动时,事件循环会看到这一点,并将对计时器回调的调用排入队列。还要注意,虽然Node.js默认只有一个主JavaScript线程,但这并不意味着节点本身是单线程的。特别是,它可以在另一个内部线程上执行I/O处理
有没有可能让我自己的函数像setTimeout一样异步
只有使用已经提供异步行为的东西并包装它。这些措施包括:
setTimeout
setImmediate
process.nextTick
- 承诺的
或然后
回调捕获
async
函数可以做到这一点,但实际上它们没有做到:async
函数中的代码一直同步运行,直到它第一次等待承诺解析(或者直到它返回)。因此,异步性实际上与上面最后一点相同:一个然后或catch
回调
不能做的事情(没有工作线程)是忙等待,就像轮询等待一样,因为在运行忙等待的线程上不会发生任何其他事情
我认为这也是一种预期的行为,因为节点js是单线程的,无法避免无限循环
但是只有一个主线程,除非您创建辅助线程
那么,这种异步行为在幕后是如何工作的呢
Node.js的主线程在循环中工作:顶级代码运行并返回,然后任何排队操作(如计时器回调)运行并返回,然后下一个排队操作运行并返回,等等。这就是setTimeout
的工作方式:当计时器启动时,事件循环会看到这一点,并将对计时器回调的调用排入队列。还要注意,虽然Node.js默认只有一个主JavaScript线程,但这并不意味着节点本身是单线程的。特别是,它可以在另一个内部线程上执行I/O处理
有没有可能让我自己的函数像setTimeout一样异步
只有使用已经提供异步行为的东西并包装它。这些措施包括:
setTimeout
setImmediate
process.nextTick
- 承诺的
然后
或捕获
回调
乍一看,您可能会认为async
函数可以做到这一点,但实际上它们没有做到:async
函数中的代码一直同步运行,直到它第一次等待承诺解析(或者直到它返回)。因此,异步性实际上与上面最后一点相同:一个然后或catch
回调
如果没有工作线程,无法做的事情是忙等待,就像您的轮询等待一样,因为在运行忙等待的线程上不会发生任何其他事情。尝试以下方法:
let done = false;
setTimeout(() => {
done = true
}, 5);
const eventLoopQueue = () => {
return new Promise(resolve =>
setImmediate(() => {
console.log('event loop');
resolve();
})
);
}
const run = async () => {
while (!done) {
console.log('loop');
await eventLoopQueue();
}
}
run().then(() => console.log('Done'));
试试这个:
let done = false;
setTimeout(() => {
done = true
}, 5);
const eventLoopQueue = () => {
return new Promise(resolve =>
setImmediate(() => {
console.log('event loop');
resolve();
})
);
}
const run = async () => {
while (!done) {
console.log('loop');
await eventLoopQueue();
}
}
run().then(() => console.log('Done'));
关键词:事件循环JavaScriptOK谢谢。这回答了我的第一个问题。第二个呢?您可以在while(true){}循环中添加延迟,这会导致它跳出并偶尔处理其他事情。。。查看下面的视频了解Javascript事件循环工作解释关键字:事件循环javascriptOkay谢谢。这回答了我的第一个问题。第二个呢?您可以在while(true){}循环中添加延迟,这会导致它跳出并偶尔处理其他事情。。。查看下面的视频,了解Javascript事件循环工作解释完美!谢谢你的解释。太好了!谢谢你的解释。