原型
异步
一、什么是单线程,和异步有什么关系
单线程:只有一个线程,同一时间只能做一件事
原因:避免DOM渲染的冲突
解决方案:异步
为什么js只有一个线程:避免DOM渲染冲突
- 浏览器需要渲染DOM
- JS可以修改DOM结构
- JS执行的时候,浏览器DOM渲染会暂停
- 两端JS也不能同时执行(都修改DOM就冲突了)
- webworker支持多线程,但是不能访问DOM
解决方案存在的问题
- 问题一:没按照书写方式执行,可读性差
- 问题二:callback中不容易模块化
二、什么是event-loop
- 事件轮询,JS实现异步的具体解决方案
- 同步代码,直接执行
- 异步函数先放在异步队列中
- 待同步函数执行完毕,轮询执行异步队列的函数
-
- setTimeout(function(){
- console.log(1);
- },100); //100ms之后才放入异步队列中,目前异步队列是空的
- setTimeout(function(){
- console.log(2); //直接放入异步队列
- })
- console.log(3) //直接执行
-
- //执行3之后,异步队列中只有2,把2拿到主线程执行,2执行完之后,异步队列中并没有任务,所以一直轮询异步队列,直到100ms之后1放入异步队列,将1拿到主线程中执行
-
- $.ajax({
- url:'./data.json',
- success:function(){ //网络请求成功就把success放入异步队列
- console.log('a');
- }
- })
-
- setTimeout(function(){
- console.log('b')
- },100)
-
- setTimeout(function(){
- console.log('c');
- })
- console.log('d')
-
- //打印结果:
- //d //d
- //c //c
- //a //b
- //b //a
-
- //真实环境不会出现dacb
三、是否用过jQuery的Deferred
- jQuery1.5的变化
- 使用jQuery Deferred
- 初步引入Promise概念
jQuery1.5之前
-
- var ajax = $.ajax({
- url:'./data.json',
- success:function(){
- console.log('success1');
- console.log('success2');
- console.log('success3');
- },
- error:function(){
- console.log('error');
- }
- })
- console.log(ajax); //返回一个XHR对象
jQuery1.5之后
-
- var ajax = $.ajax('./data.json');
- ajax.done(function(){
- console.log('success1')
- })
- .fai(function(){
- console.log('fail')
- })
- .done(function(){
- console.log('success2');
- })
- console.log(ajax); //deferred对象
-
- var ajax = $.ajax('./data.json');
- ajax.then(function(){
- console.log('success1')
- },function(){
- console.log('error1');
- })
- .then(function(){
- console.log('success2');
- },function(){
- console.log('error');
- })
-
- //使用
- var w = waithandle()
- w.then(function(){
- console.log('ok1');
- },function(){
- console.log('err2');
- })
- .then(function(){
- console.log('ok2');
- },function(){
- console.log('err2');
- })
- //还有w.wait w.fail
- 无法改变JS异步和单线程的本质
- 只能从写法上杜绝callback这种形式
- 它是一种语法糖,但是解耦了代码
- 很好的提现:开放封闭原则(对扩展开放对修改封闭)
使用jQuery Deferred
-
- //给出一段非常简单的代码,使用setTimeout函数
- var wait = function(){
- var task = function(){
- console.log('执行完成');
- }
- setTimeout(task,2000)
- }
-
- wait();
-
- //新增需求:要在执行完成之后进行某些特别复杂的操作,代码可能会很多,而且分好几个步骤
-
- function waitHandle(){
- var dtd = $.Deferred();//创建一个deferred对象
-
- var wait = function(dtd){ // 要求传入一个deferred对象
- var task = function(){
- console.log("执行完成");
- dtd.resolve(); //表示异步任务已完成
- //dtd.reject() // 表示异步任务失败或者出错
- };
- setTimeout(task,2000);
- return dtd;
- }
- //注意,这里已经要有返回值
- return wait(dtd);
- }
- /*
- *总结:dtd的API可分成两类,用意不同
- *第一类:dtd.resolve dtd.reject
- *第二类:dtd.then dtd.done dtd.fail
-
- *这两类应该分开,否则后果严重!
- *可以在上面代码中最后执行dtd.reject()试一下后果
- */
使用dtd.promise()
-
- function waitHandle(){
- var dtd = $.Deferred();
- var wait = function(){
- var task = function(){
- console.log('执行完成');
- dtd.resolve();
- }
- setTimeout(task,2000)
- return dtd.promise(); //注意这里返回的是promise,而不是直接返回deferred对象
- }
- return wait(dtd)
- }
-
-
- var w = waitHandle(); //promise对象
- $.when(w).then(function(){
- console.log('ok1');
- },function(){
- console.log('err1');
- })
- /*
- 只能被动监听,不能干预promise的成功和失败
- */
- 可以jQuery1.5对ajax的改变举例
- 说明如何简单的封装、使用deferred
- 说明promise和Defrred的区别
要想深入了解它,就需要知道它的前世今生
四、Promise的基本使用和原理
基本语法回顾
异常捕获
//规定:then只接受一个函数,最后统一用catch捕获异常
多个串联
-
- var scr1 = 'https://www.imooc.com/static/img/index/logo_new.png';
- var result1 = loadImg(src1);
- var src2 = 'https://www.imooc.com/static/img/index/logo_new.png';
- var result2 = loadImg(src2);
-
- result1.then(function(img1) {
- console.log('第一个图片加载完成', img1.width);
- return result2;
- }).then(function(img2) {
- console.log('第二个图片加载完成', img2.width);
- }).catch(function(ex) {
- console.log(ex);
- })
Promise.all和Promise.race
-
- //Promise.all接收一个promise对象的数组
- //待全部完成后,统一执行success
- Promise.all([result1, result2]).then(datas => {
- //接收到的datas是一个数组,依次包含了多个promise返回的内容
- console.log(datas[0]);
- console.log(datas[1]);
- })
-
- //Promise.race接收一个包含多个promise对象的数组
- //只要有一个完成,就执行success
- Promise.race([result1, result2]).then(data => {
- //data即最先执行完成的promise的返回值
- console.log(data);
- })
Promise标准
- 三种状态:pending,fulfilled,rejected
- 初始状态:pending
- pending变为fulfilled,或者pending变为rejected
- 状态变化不可逆
promise必须实现then这个方法
then()必须接收两个函数作为标准
then
五、介绍一下async/await(和Promise的区别、联系)
六、总结一下当前JS结局异步的方案
虚拟DOM
- vdom 是 vue 和 React 的核心,先讲哪个都绕不开它
- vdom 比较独立,使用也比较简单
- 如果面试问到 vue 和 React 和实现,免不了问 vdom
问题
- vdom 是什么?为何会存在 vdom?
什么是vdom
- virtual dom,虚拟DOM
- 用JS模拟DOM结构
- DOM变化的对比,放在JS层来做(图灵完备语言:能实现各种逻辑的语言)
- 提高重绘性能
DOM
-
- <ul id="list">
- <li class="item">Item 1</li>
- <li class="item">Item 2</li>
- </ul>
虚拟DOM:
-
- {
- tag: 'ul',
- attrs: {
- id: 'list'
- },
- children: [{
- tag: 'li',
- attrs: { className: 'item' },
- children: ['item1']
- },
- {
- tag: 'li',
- attrs: { className: 'item' },
- children: ['item2']
- }
- ]
- }
-
- //className代替class,因为class是js的保留字
浏览器最耗费性能就是DOM操作
现在浏览器执行JS性能非常低
设计一个需求场景
用jQery实现
遇到的问题
- vdom 的如何应用,核心 API 是什么
- 介绍一下 diff 算法
说一下使用 jquery 和使用框架的区别
jQuery 实现 todo-listvue 实现 todo-list
jQuery 和框架的区别
- 数据和视图的分离,解耦(开放封闭原则)
- 以数据驱动视图,只关心数据变化,DOM 操作被封装
说一下对 MVVM 的理解
- MVC
- MVVM
- 关于
ViewModel
MVVM和vue
组件化和React
hybrid
未完待续,每日更新