一、单线程模型

单线程模型指的是,JavaScript 只在一个线程上运行。也就是说,JavaScript 同时只能执行一个任务,其他任务都必须在后面排队等待

JavaScript为什么是单线程 JavaScript 之所以采用单线程,而不是多线程,跟历史有关系。JavaScript 从诞生起就是单线程,原因是不想让浏览器变得太复杂,因为多线程需要共享资源、且有可能修改彼此的运行结果,对于一种网页脚本语言来说,这就太复杂了。如果 JavaScript 同时有两个线程,一个线程在网页 DOM 节点上添加内容,另一个线程删除了这个节点,这时浏览器应该以哪个线程为准?是不是还要有锁机制?所以,为了避免复杂性,JavaScript 一开始就是单线程,这已经成了这门语言的核心特征,将来也不会改变

1.1 事件循环

出现背景
如果排队是因为计算量大,CPU 忙不过来,倒也算了,但是很多时候 CPU 是闲着的,因为 IO 操作(输入输出)很慢(比如 Ajax 操作从网络读取数据),不得不等着结果出来,再往下执行
解决方案
JavaScript 语言的设计者意识到,这时 CPU 完全可以不管 IO 操作,挂起处于等待中的任务,先运行排在后面的任务。等到 IO 操作返回了结果,再回过头,把挂起的任务继续执行下去。这种机制就是 JavaScript 内部采用的“事件循环”机制(Event Loop)

1.2 同步任务与异步任务

程序里面所有的任务,可以分成两类:同步任务synchronous和异步任务asynchronous

  • 同步任务
    • 是那些没有被引擎挂起、在主线程上排队执行的任务。只有前一个任务执行完毕,才能执行后一个任务
  • 异步任务
    • 是那些被引擎放在一边,不进入主线程、而进入任务队列的任务。只有引擎认为某个异步任务可以执行了(比如 Ajax 操作从服务器得到了结果),该任务(采用回调函数的形式)才会进入主线程执行。排在异步任务后面的代码,不用等待异步任务结束会马上运行,也就是说,异步任务不具有“堵塞”效应

      二、任务队列与事件循环(自行搜索学习)

      aHR0cHM6Ly91c2VyLWdvbGQtY2RuLnhpdHUuaW8vMjAyMC83LzEzLzE3MzQ3NTJhNGVjZmRhYmU.png
      Call Stack:执行栈
      Task Queue:任务队列(宏任务队列/消息队列)
      Microtask Queue:微任务队列
      Event Loop:事件循环机制

      三、常见的异步任务

      3.1 认识回调函数(callback)

      回调函数是异步操作最基本的方法 ```javascript function f1(callback) { // … callback(); }

function f2() { // … }

f1(f2);

  1. <a name="KAEkv"></a>
  2. ## 3.2 定时器
  3. <a name="ZXwSX"></a>
  4. ### 3.2.1 `setTimeout()`
  5. `setTimeout`函数用来指定某个函数或某段代码,在多少毫秒之后执行。它返回一个整数,表示定时器的编号,以后可以用来取消这个定时器
  6. ```javascript
  7. var timeoutID = scope.setTimeout(function[, delay, arg1, arg2, ...]);
  1. console.log(1);
  2. setTimeout('console.log(2)',1000);
  3. console.log(3);
  4. // 1
  5. // 3
  6. // 2

3.2.2 setInterval()

setInterval函数的用法与setTimeout完全一致,区别仅仅在于setInterval指定某个任务每隔一段时间就执行一次,也就是无限次的定时执行

  1. var intervalID = setInterval(func, [delay, arg1, arg2, ...]);
  1. var timer = setInterval(function() {
  2. console.log(2);
  3. }, 1000)

3.2.3 clearTimeout(),clearInterval()

setTimeoutsetInterval函数,都返回一个整数值,表示计数器编号。将该整数传入clearTimeoutclearInterval函数,就可以取消对应的定时器

  1. var id1 = setTimeout(f, 1000);
  2. var id2 = setInterval(f, 1000);
  3. clearTimeout(id1);
  4. clearInterval(id2);

3.3 DOM事件监听

  1. document.querySelector('button').onclick=function(event){
  2. console.log('按钮监听到点击行为');
  3. }

3.4 http异步请求

  1. <script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.1/jquery.js"></script>
  2. <script>
  3. $.ajax(
  4. url: "http://localhost:3000/posts",
  5. type: "get",
  6. dataType: "json",
  7. data: { "id": 5 },
  8. beforeSend: function(xhr) { console.log(xhr); },
  9. success: function(data) { console.log(data); },
  10. error: function(xhr) { console.log(xhr); },
  11. complete: function(xhr) { console.log(xhr); }
  12. )
  13. </script>