Lambda博客
  • 自我介绍
  • SSR
    • 浅谈SSR
  • React
    • 页面路由——React-Router
    • 管好你的状态——React-Redux
    • 一个哪行——React详解
    • 左膀右臂一个不少——React初探
  • 问题记录
    • js-xlsx实现纯前端导出excel表格
    • 前端开发需要了解的东西
    • 打造高性能网站
  • JavaScript学习笔记
    • 语法和API
    • js-垃圾回收
    • 收集的JS使用技巧
    • 执行机制
    • 原型和原型链
    • 执行上下文
    • 事件循环
    • JavaScript手写代码
    • 43道JS面试题
    • 悄悄的带走了你的东西——闭包详解
    • 你是个富二代吗?——JavaScript作用域链
    • 捉摸不透的女生——JavaScript类型转换
    • 这是你的女神!——JavaScript
  • 网络学习笔记
    • 强不强——HTTP-协商缓存VS强缓存
    • 网络缓存
    • 我要飞的更高——计算机网络
    • 快点!再快点!——CDN
    • 喜怒哀乐多状态——HTTP状态码
    • 你会爱上我的(ಥ_ಥ) ——TCP详解
    • 隔壁老王想篡位?门都没有——同源策略
  • 软技能
  • 安全专题
    • 保护好自己——网站安全,预防
  • 浏览器兼容性
    • 我是个好人——浏览器兼容性
  • 多图片加载——懒加载详解
  • 数据结构
  • Node
    • Node初探
  • Typescript
    • JS Plus 真香——初探 TypeScript
  • 设计模式
    • 不要花里胡哨,要一套一套——设计模式(1)
    • 学会“套路”——设计模式(2)
  • Vue
    • 实操实干——vue实例记录
    • 停下来,问问自己——Vue-刨根问底
    • 你有喘息的机会吗?——Vue,逐步了解
    • 你累吗?来来来,安利框架——Vue-初次见面
  • 小程序
    • 今天天气怎么样——记一次小程序开发
  • Webpack
    • 蛋糕分割整合工具——Webpack-前端工程化
  • 你一块,我一块——Web-modules 前端模块化
  • HTML5
    • 你会画小猪佩奇吗?—— canvas
    • 画个矢量图——HTML5-SVG
    • 听说你爱闹腾——HTML5-多媒体
    • 动画神器——HTML5-requestAnimationFrame
    • 留下痕迹——HTML5-客户端存储
    • 你知道指北针吗?——HTML5-DeviceMotionEvent
    • 你在哪啊?我在这啊——HTML5-Geolocation
    • 你到这,你到那——HTML5-拖拽
    • 你从这,到那——HTML5-拖拽上传文件
    • 开启前端之路——HTML 标签
  • 瀑布流(无限滚动)
  • 我是怎么来的?——浏览器渲染原理
  • Css
    • 由大变小,你行吗 —— 移动端
    • 动起来,这样比较炫—— CSS3 动画
    • 请不要拐弯抹角 —— CSS3 选择器
    • 想炫吗?—— CSS3 属性
    • 最后的最后——CSS自问自答
    • 万事开头难?——深入学习前端常见布局
    • 一入前端深似海——BFC剖析
    • 还有哪些好玩的东西——CSS提升
    • 那些好看的页面是怎么形成的——CSS 初识
  • 拿个小本本记下——Cookie
由 GitBook 提供支持
在本页
  • 事件循环和Promise
  • Promise
在GitHub上编辑
  1. JavaScript学习笔记

事件循环

事件循环和Promise

JS 运行的环境称之为宿主环境。

宿主环境有浏览器,服务器,桌面等…

执行栈: (call stack),一个数据结构,用于存放各种函数的执行环境,没一个函数执行之前,它的相关信息会加入到执行栈。

函数调用之前,创建执行环境,然后加入到执行栈;函数调用之后,销毁执行环境。

function A() {
  console.log("a"); //  3  创建console函数环境
  function B() {
    console.log("b"); // 5  创建console函数环境
  }
  B(); //  4  创建B函数环境
}

console.log("global"); // 1 函数环境

A(); // 2  创建A函数环境

console.log("global over"); //  6   创建console环境

JS 引擎永远执行的是执行栈的最顶部。

异步函数:某些函数不会立即执行,需要等到某个时机才会执行,这样的函数称之为异步函数。 比如事件处理函数。异步函数的执行时机,会被宿主环境控制。

浏览器宿主环境中包含 5 个线程

  1. JS 引擎:负责执行执行栈的最顶部代码

  2. GUI 线程:负责渲染页面 (DOMContentLoaded,onLoad)

  3. 事件监听线程:负责监听各种事件 (鼠标,键盘)

  4. 计时线程:负责计时 (setTimeout)

  5. 网络线程:负责网络通信 (http 请求)

当上面的线程发生了某些事情,如果该线程发现这件事情有处理程序,它会将该处理程序加入到一个叫做事件队列的内存。当 JS引擎发现,执行栈中已经没有了任何内容后,会将事件队列中第一个函数加入到执行队列。

setTimeout(() => {
  console.log("1"); //   2
  setTimeout(() => {
    console.log("3"); //    4
  }, 0);
}, 0);

setTimeout(() => {
  console.log("2"); //    3
}, 0);

for (let i = 0; i < 1000; i++) {
  console.log(i); //  1 --- 999
}

JS 引擎对事件队列的取出执行方式,以及与宿主环境的配合,称之为事件循环。

事件队列在不同的宿主环境中有所差异,大部分宿主环境会将事件队列进行细分。在浏览器中,事件队列分为两种

  • 宏任务

    (队列)

    • 计时器结束的回调、事件回调、http 回调等大部分异步函数进入宏队列

  • 微任务

    (队列)

    • Promise 产生的回调进入微队列

当执行栈清空时,JS 引擎首先会将微任务中的所有任务依次执行结束,如果没有微任务,则执行宏任务。

Promise

Promise 对象表示任务,它用一种标准格式处理异步任务。

Promise 构造函数中传入的任务函数会被立即执行(同步)。resolve 和 reject 是异步执行。

resolve 调用后,把任务标记为成功,可以通过 Promise 对象的 then 函数注册处理程序,该程序会在任务标记为成功后执行,是异步的。

setTimeout(function() {
  console.log("A");
}, 0);
var obj = {
  func: function() {
    setTimeout(function() {
      console.log("B");
    }, 0);
    return new Promise(resolve => {
      console.log("C");
      resolve();
      console.log("D");
    });
  }
};
obj.func().then(function() {
  console.log("E");
});
console.log("F");

// C  D  F  E  A  B
上一页执行上下文下一页JavaScript手写代码

最后更新于3年前