随笔- 137  评论- 0  文章- 0 

【javascript】异步-事件轮询-任务队列-工作队列(job queque)

异步

异步编程的核心: 现在 与 稍后 的部分之间的关系。
例子: 去吃饭排队,先拿一个号,排到了手机会有消息收到。在这个时候,可以取买点喝的。

现在:排队拿号 -> 买水 。
稍后:短信通知排到了,开吃!

event loop 事件轮询

我们将事件轮询理解成一个永动机,它一直会去找某一个队列【就可以理解成一个数组】里面的是否有执行的任务,如果有,那么会去执行。

模拟代码:

	var eventLoop = [];
	var event;
	// 永远执行
	while (true) {
	    // 检查队列是否有数据
	    // 执行一个tick
		if (eventLoop.length > 0) {
			event = eventLoop.shift();
			try {
				event();
			} 
			catch(err) {
				reportError(err); // report Error stack info 
			}
			
		}
	}

js引擎 遇到异步代码块,会将它放到【不一定是马上】任务队列里面,当主线程执行完所有代码的时候,会从这个任务队列里面取任务,如果有就执行。

setTimeout 不会将回调放在事件轮询队列上,定时器超时的时候,环境才会把你的回调放进事件轮询,这样在未来的某个tick中将会被取出执行。


虽说js是单线程,但是在事件轮询 和 并发模型机制上,并非是单线程。 除了主线程callstack , 还有一个专门处理回调函数或者事件的线程(在浏览器里面就是webAPI,node里面就是线程 )。外面有一个task queue,这里就是回调等待的地方。

比如遇到了A , A 有一个回调,A函数执行了,A的回调放到了 另外的线程,另外的线程在满足一定条件(可能是setTimeout 或者response响应)之后就会将这个回调放到 task queue 里面, callstack [必须]clear之后会马上去task queue 里面一个一个执行这个队列的代码,执行完一个,task queue的这个就回收。

nice video: https://www.youtube.com/watch?v=8aGhZQkoFbQ
在这里插入图片描述

[大白话]: 主线程的代码执行完毕之后,然后会去task queue(任务队列)去执行队列中的任务。

所以

	console.log("one")
	setTimeout(()=>{
		console.log("two")
	}, 0)
	console.log("three")

结果会是:

	"one"
	"three"
	"two"

而不是one two three

但是ES6 引入了promise generator async 等异步概念,他们是不是也是被放到了task queque呢。。答案是否定的。

在任意特定的时刻,一次只有一个队列中的一个事件可以被处理,当事件执行的时候,它可以间接的或者直接的引发(导致)一个或者更多的后续事件。


es6引入了新的概念:job queque(工作队列), Promise的异步行为是基于job的

to be continued

posted on 2019-01-22 19:05  狂奔的冬瓜  阅读(...)  评论(...编辑  收藏