乐趣区

关于前端:JS-setTimeout的异步操作如何实现

外围有三个:同步事件音讯队列,异步事件音讯队列,事件循环系统。(后文简称同步队列、提早队列、事件循环)

浏览器中有一个同步事件音讯队列,
所有运行在主线程上的工作,都须要先增加到同步队列,而后事件循环系统再依照先后顺序执行音讯队列中的工作。

不思考异步事件,同步事件的流程如下。

同步队列:
task_queue
sync_task1, sync_task2, sync_task3, …

事件循环:
getSyncTask; // (sync_task1)
processSyncTask;
getSyncTask; // (sync_task2)
processSyncTask;
getSyncTask; // (sync_task3)
processSyncTask;

引入异步事件的变动是,每次执行完同步工作后,都会去获取异步工作(未必能获取到)

事件循环的流程如下。

同步队列:
task_queue
sync_task1, sync_task2, sync_task3, …

提早队列:
delay_task_queue
async_task

事件循环:
getSyncTask; // (sync_task1)
processSyncTask;
getAsyncTask; // 无后果(如延迟时间未到)

getSyncTask; // (sync_task2)
processSyncTask;
getAsyncTask; // (async_task)
processAsyncTask; // 执行异步事件

getSyncTask; // (sync_task3)
processSyncTask;
getAsyncTask; // 无异步事件;

当通过 JavaScript 调用 setTimeout 设置回调函数的时候,渲染过程将会创立一个回调工作,蕴含了回调函数 name、currentTime、delayTime;
创立好回调工作之后,再将该工作增加到提早执行队列中;

还要重点关注 getAsyncTask 以及 processAsyncTask 的执行机会,在下面的示例中,解决完同步队列中的一个工作之后,就开始执行 getAsyncTask 函数。getAsyncTask 函数会依据发动工夫和延迟时间计算出到期的工作,而后顺次执行这些到期的工作。等到期的工作执行实现之后,再持续下一个循环过程。如果同步工作的工夫过久,那异步工作的执行事件未必会远大于设置延迟时间。

同步更新到本人的语雀
https://www.yuque.com/diracke…

退出移动版